„Здрасти, Амиго!“

„Здравей, Билаабо! Как е животът?“

"Страхотно. Вчера се опитах да се отърва от някои паразити, но досега не съм имал особен успех. И тогава отново трябваше да прекарам нощта в кофата за боклук."

„И така... всичко все още ли е страхотно?“

— Може да се каже така.

"Добре. Какво имаш за мен днес?"

„Днес ще ви разкажа за класа RandomAccessFile .“

RandomAccessFile и др. - 1

„Работата е там, че FileInputStream и FileOutputStream представят файлове като потоци: можете само да ги четете и пишете последователно.“

„Това не винаги е много удобно. Понякога трябва да напишете няколко реда в средата на файл or да прочетете няколко страници текст от края на многомегаbyteов файл. Не би било много ефективно да се чете целия файл за тези задачи."

„ Класът RandomAccessFile е създаден, за да разреши този проблем. Можете да го използвате, за да пишете навсякъде във file, да четете от него, Howто и да четете и пишете във file едновременно.“

"Колко интересно!"

"Да. Всъщност е доста удобно."

„Но How се чете от произволно място?“

„Всичко е доста просто. Представете си, че имате отворен текстов редактор, като например Notepad. Той има курсор. Когато въвеждате нещо, текстът се добавя където и да е курсорът. Четенето на файл е същото. Четенето започва от където и да е 'курсорът'. Когато четете/пишете, курсорът се движи автоматично."

„Ето, ще е по-добре да ви покажа един пример:“

Четене на файл:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// Move the «cursor» to the 100th character.
raf.seek(100);

// Read the line starting from the current cursor position until the end of the line.
String text = raf.readLine();

// Close the file.
raf.close();

„В този пример бих искал да насоча вниманието ви към две неща:“

"Първо, създаването на обекта RandomAccessFile . Вторият аргумент е буквата r. Това означава, че файлът е отворен за четене ( r - read ). Ако искате да отворите файл за четене и запис, трябва да подадете « rw » към конструктора, instead of само « r »."

„Второ, погледнете метода за търсене. Можете да използвате този метод, за да прескачате във file и да промените позицията на курсора за текущата операция за четене/запис. Когато файлът е отворен за първи път, курсорът е зададен на 0-ия byte. Или, по-точно, преди нулевия byte."

„Правилно ли разбрах? Отваряме file и курсорът е в самото начало — на позиция 0. След това извикваме търсене и преместваме курсора до 100-ия byte. И когато извикаме readLine , той започва да чете от стотния byte .Нали?"

"Да. Но искам да обърна внимание на факта, че методът за търсене ви позволява да прескачате произволно във file. Например:"

Четене на файл:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// The "cursor" is at the 0th character.
String text1 = raf.readLine();

// Move the "cursor" to the 100th character.
raf.seek(100);
String text2 = raf.readLine();

// Move the "cursor" to the 0th character.
raf.seek(0);
String text3 = raf.readLine();

// Close the file
raf.close();

„В този пример първо четем ред, започващ от 0-ия byte. След това скачаме до стотния byte и четем ред там. След това скачаме отново до 0-ия byte и четем ред. Това означава, че text1 и text3 са идентични струни."

"А. Това прави нещата по-ясни."

„Страхотно. Тогава ето още един пример:“

Четене на файл:
// rw - read/write, the file is opened for reading and writing.
RandomAccessFile raf = new RandomAccessFile("seek.txt", "rw");

// Write to the file, starting from the 0th byte.
raf.writeBytes("It is a string");

// Move the "cursor" to the 8th character.
raf.seek(8);

// Write "surprise!" to the file.
raf.writeBytes("surprise!");

// Close the file.
raf.close();

"Тук отваряме file за четене и запис, като предаваме « rw » ( четене/запис ) на конструктора."

„След това пишем „ това е низ “ във file.

„След това преместваме курсора на 8-ия byte (който случайно е началото на думата „низ“)“

„Тогава пишем „ изненада !

"В резултат на това файлът съдържа « Това е изненада

„Значи byteовете не се вмъкват в средата на file, а по-скоро заместват тези, които са бor там?“

— Да.

„Ами ако преместим курсора в самия край на file?“

"Тогава byteовете ще бъдат записани до края и файлът ще стане по-голям. Така че би било почти като писане на текст в текстов редактор."

„Хм. Мисля, че разбирам всичко. Бихте ли предоставor пълен списък на методите на класа RandomAccessFile ?“

"Разбира се, заповядай:"

Метод Описание
int read() Чете един byte и го връща
int read(byte b[], int off, int len) Чете масив от byteове
int read(byte b[]) Чете масив от byteове
void readFully(byte b[]) Чете масив от byteове и изчаква добавянето на нови byteове, ако няма достатъчно за запълване на масива
int skipBytes(int n) Пропускане на n byteа. С други думи, това премества курсора напред с n byteа.
void write(int b) Записва един byte в местоположението на курсора
void write(byte b[]) Записва масив от byteове в местоположението на курсора
void write(byte b[], int off, int len) Записва масив от byteове в местоположението на курсора
long getFilePointer() Връща номера на byteа, към който сочи курсорът. Може да варира от 0 до дължината на file
void seek(long pos) Премества «курсора», използван за четене/запис, до посоченото място
long length() Връща дължината на file
void setLength(long newLength) Задава нова дължина на file. Ако файлът е по-голям, той се съкращава; ако е по-малък, тогава разширява file и запълва новото пространство с нули
void close() Затваря file
boolean readBoolean() Чете булева стойност от текущата позиция на курсора във file
byte readByte() Чете byte от текущата позиция на курсора във file
char readChar() Чете знак от текущата позиция на курсора във file
int readInt() Чете int от текущата позиция на курсора във file
long readLong() Чете дълго от текущата позиция на курсора във file
float readFloat() Чете float от текущата позиция на курсора във file
double readDouble() Прочита двойно от текущата позиция на курсора във file
String readLine() Чете ред от file и го връща
void writeBoolean(boolean v) Записва булево във file (започвайки от позицията на курсора)
void writeByte(int v) t Записва byte във file (започвайки от позицията на курсора)
void writeChar(int v) Записва char във file (започвайки от позицията на курсора)
void writeInt(int v) Записва int във file (започвайки от позицията на курсора)
void writeLong(long v) Записва long във file (започвайки от позицията на курсора)
void writeFloat(float v) Записва float във file (започвайки от позицията на курсора)
void writeDouble(double v) Записва двойно във file (започвайки от позицията на курсора)
void writeBytes(String s) Записва низ във file (започвайки от позицията на курсора)
void writeChars(String s) Записва низ във file (започвайки от позицията на курсора)

"Хм. И така, тук няма нищо ново. Освен може би двойките методи seek()/getFilePointer() и length()/setLength()."

„Да, Амиго. Всичко е почти същото. Но не е ли удобно?“

„Удобно е. Благодаря ти, Билаабо, за интересния урок и за примерите, които ми даде.“

„Радвам се да помогна, амиго, приятелю!“