Чтение и запись двоичных данных: классы BinaryReader и BinaryWriter
Операции чтения и записи на уровне отдельных байтов слишком примитивны, и пользоваться ими неудобно. По этой причине в .NET Framework предусмотрены гораздо более практичные способы чтения и записи данных в файловые потоки. В этом разделе мы покажем, как использовать классы BinaryReader и BinaryWriter для чтения и записи строк и примитивных типов данных. Эти классы автоматически преобразуют примитивные типы в двоичный формат, подходящий для сохранения на диске или пересылки по сети.
Объекты BinaryReader и BinaryWriter создаются посредством многоуровневого объединения конструкторов потоков. Иначе говоря, конструктору класса потока более высокого уровня вместо строки передается существующий объект потока. Пример приведен ниже:
Dim aFileStream As FileStream Try aFileStream = New FileStream("c:\data.txt".FileMode.OpenOrCreate._ FileAccess.Write) Dim myBinaryWriter As New BinaryWriter(aFileStream) myBinaryWriter.Write("Hello world") myBinaryWriter.writed) Catch e as Exception Console.Writeline(e.stacktrace) Finally If not(aFileStream is Nothing) Then aFileStream.Close() End Try
Конструктору класса BinaryWriter передается объект файлового потока aFileStream. Полученный в результате поток обладает расширенными возможностями и поддерживает запись текстовых и числовых данных в файл в двоичном формате. Пример записи с использованием класса BinaryWriter:
myBinaryWriter.Write("Hello world") myBinaryWriter.writed)
Работа этого фрагмента основана на перегрузке метода Write в классе BinaryWriter, позволяющей легко записывать в поток любые базовые типы данных. Ниже перечислены основные перегруженные версии:
- Sub Write(Byte)
- Sub Write(Byte())
- Sub Write(Char)
- Sub Write(Char())
- Sub Write(Decifnal)
- Sub Write(Double)
- Sub Write(Short)
- Sub Write(Integer)
- Sub Write(Long)
- Sub Write(Byte)
- Sub Write(Single)
- Sub Write(String)
На рис. 9.3 показано, как созданный файл выглядит в шестнадцатеричном редакторе. Как видно из рисунка, строка записана в виде кодов отдельных символов, но число кодируется четырьмя байтами.
К сожалению, хотя для записи в поток существуют различные перегруженные версии метода Write, при чтении записанной информации средствами класса BinaryReader не существует аналогичных перегруженных методов Read. Вместо этого для каждого типа данных определяется собственная версия Read – ReadString, Readlnt32 (для типа Integer), ReadChar и т. д. Вы должны знать, что и в каком порядке было записано в файл; в противном случае восстановить исходные данные не удастся. Следующий фрагмент показывает, как выполняется чтение в приведенном выше примере:
aFileStream = New FileStream("с:\data.txt", FileMode.Open. FileAccess.Read) Dim myBinaryReader As New BinaryReader(aFileStream) Console._ WriteLine(myBinaryReader.ReadString) Console.WriteLine(myBinaryReader.Readlnt32)
Рис. 9.3. Файл, записанный с применением класса BinaryWriter, в шестнадцатеричном представлении
Если вы хотите организовать обобщенное чтение двоичных данных и вас не интересует, какому типу соответствуют прочитанные байты, воспользуйтесь методом PeekChar. Этот метод проверяет, равен ли следующий байт -1 (признак конца файла в .NET). Цикл выглядит примерно так:
While myBInaryReader.PeekChar() <> -1 ' Прочитать следующий байт Loop
Примечание
Поскольку чтение из файловых потоков буферизуется автоматически, в данном примере нет необходимости добавлять новый уровень, передавая объект потока конструктору BufferedStream.