Философия Java3
Шрифт:
}
} /// ~
Объект StringBuilder sb служит для объединения всего прочитанного текста (включая переводы строк, поскольку метод readLine их отбрасывает). В завершение файл закрывается методом close.
Чтение из памяти
В этой секции результат String файла BufferedInputFile.read используется для создания StringReader. Затем символы последовательно читаются методом read, и каждый следующий символ посылается на консоль.
II io/MemoryInput java import j^va 10 *;
public class Memorylnput {
public static void main(String[] args) throws IOException {
StringReader in = new StringReader(
BufferedlnputFile.read("MemoryInput java"));
int c.
while((c = in readO) != -1)
System out print((char)c),
}
} III ~
Обратите
Форматированное чтение из памяти
Для чтения «форматированных» данных применяется класс DatalnputStream, ориентированный на ввод/вывод байтов, а не символов. В данном случае необходимо использовать классы иерархии InputStream, а не их аналоги на основе класса Reader. Конечно, можно прочитать все, что угодно (например, файл), через InputStream, но здесь используется тип String.
//• io/FormattedMemoryInput.java import java.io.*,
public class FormattedMemorylnput {
public static void main(Stnng[] args) throws IOException { try {
DatalnputStream in = new DataInputStream( new ByteArrayInputStream(
BufferedlnputFile.read(
"FormattedMemorylnput java") getBytes(
))).
while(true)
System.out.pri nt((char)i n.readByte): } catch(EOFException e) {
System.err.println(uEnd of stream"); продолжение &
} /// ~
Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArraylnputStream, в классе String предусмотрен метод getBytes. Полученный ByteArraylnputStream представляет собой поток InputStream, подходящий для передачи DatalnputStream.
При побайтовом чтении символов из форматированного потока DatalnputStream методом readByte любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available, который сообщает, сколько еще осталось символов. В следующем примере показано, как читать файл побайтно:
//: io/TestEOF.java
// Проверка достижения конца файла одновременно
// с чтением из него по байту.
import java.io *;
public class TestEOF {
public static void main(String[] args) throws IOException {
DatalnputStream in = new DataInputStream( new BufferedInputStream(
new FilelnputStreamCTestEOF java"))), while(in.available != 0)
System.out print((char)in readByteO);
}
} ///:-
Заметьте, что метод available работает по-разному в зависимости от источника данных; дословно его функция описывается следующим образом: «количество байтов, которые можно прочитать без блокировки». При чтении из файла это означает весь файл, но для другого рода потоков
Определить конец входного потока можно и с помощью перехвата исключения. Впрочем, применение исключений в таких целях считается злоупотреблением.
Вывод в файл
Объект FileWriter записывает данные в файл. При вводе/выводе практически всегда применяется буферизация (попробуйте прочитать файл без нее, и вы увидите, насколько ее отсутствие влияет на производительность — скорость чтения уменьшится в несколько раз), поэтому мы присоединяем надстройку BufferedWriter. После этого подключается PrintWriter, чтобы выполнять форматированный вывод. Файл данных, созданный такой конфигурацией ввода/вывода, можно прочитать как обычный текстовый файл.
//: io/BasicFileOutput.java
import java.io.*;
public class BasicFi1eOutput {
static String file = "BasicFileOutput out", public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader( new StringReader(
BufferedlnputFile read("BasicFileOutput java"))), PrintWriter out = new PrintWriter(
new BufferedWriter(new Fi1eWriter(fi1e))), int lineCount = 1, String s,
whi 1 e((s = in readLineO) != null )
out println(lineCount++ + " " + s). out closeO.
// Вывод содержимого файла
System out println(BufferedInputFile readCfile)).
}
} /// ~
При записи строк в файл к ним добавляются их номера. Заметьте, что надстройка LineNumberlnputStream для этого не применяется, поскольку этот класс тривиален, да и вообще не нужен. Как и показано в рассматриваемом примере, своя собственная нумерация ничуть не сложнее.
Когда данные входного потока исчерпываются, метод readLine возвращает null. Для потока outl явно вызывается метод close; если не вызвать его для всех выходных файловых потоков, в буферах могут остаться данные, и файл получится неполным.
Сокращенная форма вывода текстового файла
В Java SE5 у PrintWriter появился вспомогательный конструктор. Благодаря ему вам не придется вручную выполнять всю работу каждый раз, когда вам потребуется создать текстовый файл и записать в него данные. Вот как выглядит пример BasicFileOutput.java в обновленном виде:
//• io/FileOutputShortcut java import java io *.
public class FileOutputShortcut {
static String file = "FileOutputShortcut.out", public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader( new StringReader(
BufferedlnputFile readC'FileOutputShortcut java"))); // Сокращенная запись PrintWriter out = new PrintWriter(file); int lineCount = 1, String s,
while((s = in.readLineO) != null )
out println(lineCount++ + " + s). out closeO.
// Вывод содержимого файла-
System out.printin(BufferedInputFile readCfile)); продолжение &
}
} ///;-
Буферизация по-прежнему обеспечена, но вам не приходится включать ее самостоятельно. К сожалению, для других распространенных операций сокращенной записи не предусмотрено, поэтому типичный код ввода/вывода по-прежнему содержит немало избыточного текста.