Читайте также: |
|
Параметр, передаваемый методу, определяет новую позицию в байтах. Позиция отсчитывается от начала файла. После обращения к методу seek() операция чтения извлечет байт, находящийся в текущей позиции, а операция записи разместит в этой позиции новое значение.
B классе RandomAccessFile определены методы read() и write().Этот класс также реализует интерфейсы DataInput и DataOuput, т.е. в этом классе доступны методы чтения и записи простых типов, например readInt() и writeDouble().
Ниже приведен пример, демонстрирующий ввод-вывод с произвольным доступом. В программе производится запись в файл шести значений типа double. Потом эти значения читаются, причем порядок чтения отличается от порядка записи.
// Работа с файламипроизвольногодоступа
import java.io.*;
class RandomAccessDemo {
public static void main(String args[])
{
double data[] = { 19.4, 10.1, 123.54, 33.0, 87.9, 74.25 };
double d;
RandomAccessFile raf;
try {
// Открытиефайлапроизвольногодоступа
raf = new RandomAccessFile("random.dat", "rw");
}
catch (FileNotFoundException exc) {
System. out. println("Cannot open file.");
return;
}
try {
// Записьданных в файл
for (int i=0; i < data.length; i++) {
raf.writeDouble(data[i]);
}
// Чтениезаписанныхзначений.
// Дляустановкитекущейпозиции // используетсяметод seek()
raf.seek(0); // Первоезначение double
d = raf.readDouble();
System. out. println("First value is " + d);
raf.seek(8); // Второезначение double
d = raf.readDouble();
System. out. println("Second value is " + d);
raf.seek(8 * 3); //
d = raf.readDouble();
System. out. println("Fourth value is " + d);
System. out. println();
// Чтениеостальныхзначений
System. out. println("Here is every other value: ");
for (int i=0; i < data.length; i+=2) {
raf.seek(8 * i); // i-е значение double
d = raf.readDouble();
System. out. print(d + " ");
}
}
catch (IOException exc) {
System. out. println("File error.");
}
try {
raf.close();
} catch (IOException exc) {
System. out. println("Error closing file.");
}
}
}
Обратите внимание на расположение каждого значения. Поскольку значение типа double занимает 8 байтов, начало каждого следующего числа отстоит от начала предыдущего на это расстояние. Другими словами, первое значение начинается в позиции 0, второе — в позиции 8, третье — в позиции 16 и т.д. Таким образом, чтобы прочитать четвертое значение, надо установить в программе текущую позицию, равную 24.
Вопросы для текущего контроля
1. Какой класс надо использовать для создания файла с произвольным доступом?
2. Как установить текущую позицию в файле?
Использование символьных потоков
Прочитав предыдущий раздел, вы могли составить представление о возможностях байтовых потоков Java. Однако в том, что касается ввода-вывода символов, байтовые потоки далеко не идеальны. Для решения этих задач в Java определены классы символьных потоков. Наверху иерархии классов, поддерживающих символьные потоки, находятся абстрактные классы Reader и Writer. Методы класса Reader приведены в табл. 7, а методы класса Writer — в табл. 8. Большинство указанных методов может генерировать исключение IOException. Методы, определенные в указанных двух абстрактных классах, доступны во всех подклассах. Таким образом, они формируют минимальный набор функций ввода-вывода, общий для всех символьных потоков.
Таблица 7. Методы, определенные в классе Reader
Метод | Описание |
abstract void close () | Закрывает источник входных данных. В дальнейшем при попытке чтения генерируется исключение IOException |
void mark (int numChars) | Помечает текущую позицию входного потока маркером, который доступен до тех пор, пока не будет прочитано numChars символов |
boolean markSupported() | Возвращает значение true, если поток поддерживает методы mark() и reset() |
int read() | Возвращает целочисленное представление очередного символа из входного потока. При достижении конца файла возвращает значение, равное -1 |
int read (char buffer[ ]) | Предпринимает попытку прочитать buffer.length символов и поместить их в массив buffer. Возвращает число реально прочитанных символов. При достижении конца файла возвращается значение, равное -1 |
abstract int read (char buffer[ ], int offset, int numChars) | Предпринимает попытку прочитать numChars символов и поместить их в массив buffer, начиная с элемента buffer[offset].Возвращает число реально прочитанных символов. При достижении конца файла возвращается значение, равное -1 |
int read (CharBuffer buffer) | Предпринимает попытку заполнить буфер buffer символами, прочитанными из входного потока. При достижении конца файла возвращается значение, равное -1. CharBuffer — это класс, представляющий последовательность символов, например, строку |
boolean ready() | Возвращает значение true, если следующий запрос на получение символа может быть выполнен немедленно. В противном случае возвращается значение false |
void reset() | Восстанавливает текущую позицию в соответствии с ранее установленным маркером |
long skip(long numChars) | Пропускает numChars символов из входного потока. Возвращает число реально пропущенных символов |
Таблица 8. Методы, определенные в классе Writer
Метод | Описание |
Writer append (char ch) | Записывает символ ch в конец текущего потока. Возвращает ссылку на поток |
Writer append (CharSequence chars) | Записывает указанные символы в конец текущего потока. Возвращает ссылку на поток. CharSequence — это интерфейс, в котором описаны только операции чтения последовательности символов |
Writer append (CharSequence chars, int begin, int end) | Записывает указанные символы в конец текущего потока символы из CharSequence от begin до end. Возвращает ссылку на поток. CharSequence — это интерфейс, в котором описаны только операции чтения последовательности символов |
abstract void close() | Закрывает выходной поток. В дальнейшем при попытке записи в поток генерируется исключение IOException |
abstract void flush() | Записывает текущее содержимое буфера на устройство. В результате выполнения данной операции буфер очищается |
void write (int ch) | Записывает в выходной поток один символ. В качестве параметра указывается значение int, что позволяет передавать методу значение, полученное в результате вычисления выражения |
void write (char buffer[ ]) | Записывает в выходной поток массив символов |
abstract void write(char buffer[ ], int offset, int numChars) | Записывает в выходной поток numChars символов из массива buffer, начиная с элемента buffer[offset] |
void write (String str) | Записывает в выходной поток строку str |
void write(String str, int offset, int numChars) | Записывает в выходной поток часть строки str, которая начинается с символа с номером offset и содержит numChars символов |
Консольный ввод посредством символьных потоков
Если код подлежит интернационализации, то при организации ввода с консоли символьным потокам следует отдать предпочтение перед байтовыми потоками. Но, поскольку System.in — это байтовый поток, необходимо сформировать для него оболочку в виде класса, являющегося потомком Reader. Наилучший класс для чтения с консоли— это BufferedReader, поддерживающий буферизованный входной поток. Однако объект BufferedReader невозможно сформировать непосредственно из System.in. Сначала надо преобразовать байтовый поток в символьный. Эту задачу можно решить посредством класса InputStreamReader, преобразующего байты в символы. Для того чтобы получить объект InputStreamReader, связанный с System.in, надо использовать следующий конструктор:
InputStreamReader(InputStream inputStream)
Поскольку переменная System.in ссылается на объект типа InputStream, ее можно указать в качестве параметра конструктора. Затем на базе объекта InputStreamReader можно создать объект BufferedReader, используя конструктор
BufferedReader(Reader inputReader)
где inputReader — это поток, который связывается с создаваемым экземпляром класса BufferedReader. Объединяя обращения к указанным выше конструкторам в одну операцию, мы получаем представленную строку кода. Она создает объект BufferedReader, связанный с клавиатурой.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
После выполнения данного выражения переменная br будет ссылаться на символьный поток, связанный с консолью посредством объекта System, in.
Дата добавления: 2015-07-10; просмотров: 167 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Чтение и запись двоичных данных | | | Чтение символов |