Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

Сохранение и восстановление данных

PrintWriter форматирует данные так, чтобы их мог прочитать человек. Однако для вывода информации, предназначенной для другого потока, следует использовать классы DataOutputStream (для записи данных) и DatalnputStream (для чтения данных). Конечно, природа этих потоков может быть любой, но в нашем случае открывается файл, буферизованный как для чтения, так и для записи. Надстройки DataOutputStream и DatalnputStream ориентированы на посылку байтов, поэтому для них требуются потоки OutputStream и InputStream:

II- io/StoringAndRecoveringData.java import java io *,

public class StoringAndRecoveringData {

public static void main(String[] args) throws IOException {

DataOutputStream out = new DataOutputStream( new BufferedOutputStream(

new FileOutputStreamC'Data.txt"))); out.writeDouble(3.14159); out.writeUTFCThat was pi"); out. writeDoubled. 41413); out.writeUTFC"Square root of 2"); out.closeO;

DatalnputStream in = new DataInputStream( new BufferedlnputStreamC

new FileInputStreamCData.txt"))); System.out println(in readDoubleO). // Только readUTFO нормально читает // строки в кодировке UTF для Java; System out pri ntl n( in readUTFO); System, out. pri ntl n( in readDoubleO); System out. pri ntl n( in readUTFO);

}

} /* Output; 3.14159 That was pi 1.41413

Square root of 2 *///;-

Если данные записываются в выходной поток DataOutputStream, язык Java гарантирует, что эти данные в точно таком же виде будут восстановлены входным потоком DatalnputStream — невзирая на платформу, на которой производится запись или чтение. Это чрезвычайно ценно, и это знает любой, так или иначе соприкасавшийся с вопросами переносимости программ. Если Java поддерживается на обеих платформах, проблема исчезает сама собой.

Единственным надежным способом записать в поток DataOutputStream строку (String) так, чтобы ее можно было потом правильно считать потоком DatalnputStream, является кодирование UTF-8, реализуемое методами readUTF и writeUTF. UTF-8 — это разновидность кодировки Юникод, в которой каждый символ хранится в двух байтах. Если вы работаете только с кодировкой ASCII, «удвоение» данных в Юникоде приводит к неоправданным затратам дискового пространства и (или) нагрузке на сеть. Поэтому UTF-8 кодирует символы ASCII одним байтом, а символы из других кодировок записывает двумя или тремя байтами. Вдобавок в первых двух байтах строки хранится ее длина. Впрочем, методы readUTF и writeUTF используют специальную модификацию UTF-8 для Java23 (она описана в документации JDK), и для правильного считывания из другой программы (не на Java) строки, записанной методом writeUTF, вам придется добавить в нее специальный код, позволяющий верно ее считать.

Методы readUTF и writeUTF позволяют смешивать строки и другие типы данных, записываемые потоком DataOutputStream, так как вы знаете, что строки будут правильно сохранены в Юникоде и их будет просто воспроизвести потоком DatalnputStream.

Метод writeDouble записывает число double в поток, а соответствующий ему метод readDouble затем восстанавливает его (для других типов также существуют подобные методы). Но, чтобы правильно интерпретировать любые данные, вы должны точно знать их расположение в потоке; при наличии такой информации прочитать число double как какую-то последовательность байтов или символов не представляет сложности. Поэтому данные в файле должны иметь определенный формат, или вам придется использовать дополнительную информацию, показывающую, какие именно данные находятся в определенных местах. Заметьте, что сериализация объектов (описанная в этой главе чуть позже) часто предоставляет простейший способ записи и восстановления сложных структур данных.

Чтение/запись файлов с произвольным доступом

Как уже было замечено, работа с классом RandomAccessFile напоминает использование совмещенных в одном классе потоков DatalnputStream и DataOutputStream (они реализуют те же интерфейсы Datalnput и DataOutput). Кроме того, метод seek позволяет переместиться к определенной позиции и изменить хранящееся там значение.

При использовании RandomAccessFile необходимо знать структуру файла, чтобы правильно работать с ним. Класс RandomAccessFile содержит методы для чтения и записи примитивов и строк UTF-8. Пример:

//: io/UsingRandomAccessFile.java import java.io.*,

public class UsingRandomAccessFile { static String file = "rtest.dat". static void displayО throws IOException {

RandomAccessFile rf = new RandomAccessFile(file, "r"). for(int i =0. i <7, i++) System.out println(

"Значение " + i + " " + rf .readDoubleO); System.out.pri ntln(rf.readUTF); rf.closeO;

}

public static void main(String[] args) throws IOException {

RandomAccessFile rf = new RandomAccessFile(file, "rw"). for(int i = 0; i < 7; i++)

rf writeDouble(i*1.414); rf writeUTFCThe end of the file"), rf closeO. displayO,

rf = new RandomAccessFile(file, "rw"); rf.seek(5*8); rf writeDouble(47.0001), rf.closeO; displayO;

}

} /* Output; Значение 0; 0.0 Значение 1. 1.414 Значение 2; 2.828 Значение 3- 4 242 Значение 4; 5.656 Значение 5; 7.069999999999999 Значение 6. 8.484 The end of the file Значение 0; 0.0 Значение 1; 1.414 Значение 2; 2 828 Значение 3; 4.242 Значение 4; 5.656 Значение 5; 47.0001 Значение 6; 8.484 The end of the file *///;-

Метод display открывает файл и выводит семь значений в формате double. Метод main создает файл, открывает и модифицирует его. Поскольку значение double всегда занимает 8 байт, для перехода к пятому числу методу seek следует передать смещение 5*8.

Как упоминалось ранее, класс RandomAccessFile отделен от остальных классов иерархии ввода/вывода, если не считать того факта, что он реализует интерфейсы Datalnput и DataOutput. Приходится предполагать, что для этого RandomAccessFile правильно организована буферизация, потому что включить ее в программе не удастся.

Некоторая свобода выбора предоставляется только со вторым аргументом конструктора: RandomAccessFile может открываться в режиме чтения ("г") или чтения/записи ("rw").

Также стоит рассмотреть возможность употребления вместо класса RandomAccessFile механизма отображаемых в память файлов.

Каналы

В этой главе были коротко упомянуты классы каналов PipedlnputStream, Piped-OutputStream, PipedReader и PipedWriter. Это не значит, что они редко используются или не слишком полезны, просто их смысл и действие нельзя донести до понимания до тех пор, пока не объяснена многозадачность: каналы предназначены для связи между отдельными потоками программы. Они будут описаны позднее.

Поделиться:
Популярные книги

Ненаглядная жена его светлости

Зика Натаэль
Любовные романы:
любовно-фантастические романы
6.23
рейтинг книги
Ненаглядная жена его светлости

Черный Маг Императора 19

Герда Александр
19. Черный маг императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 19

Камень. Книга вторая

Минин Станислав
2. Камень
Фантастика:
фэнтези
8.52
рейтинг книги
Камень. Книга вторая

Первый среди равных. Книга II

Бор Жорж
2. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга II

Гезат

Чернобровкин Александр Васильевич
22. Вечный капитан
Фантастика:
альтернативная история
5.25
рейтинг книги
Гезат

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Я еще царь. Книга XXX

Дрейк Сириус
30. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я еще царь. Книга XXX

Старая школа рул

Ромов Дмитрий
1. Второгодка
Фантастика:
альтернативная история
6.00
рейтинг книги
Старая школа рул

Один на миллион. Трилогия

Земляной Андрей Борисович
Один на миллион
Фантастика:
боевая фантастика
8.95
рейтинг книги
Один на миллион. Трилогия

Хозяин Стужи 8

Петров Максим Николаевич
8. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 8

Охотник за головами

Вайс Александр
1. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Охотник за головами

Родословная. Том 2

Ткачев Андрей Юрьевич
2. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 2