ОК, давайте начнем с того, что делает ваш код (см. Мои добавленные комментарии):
// create a FileStream to data.txt (a file with a .txt extension - not necessarily a text file)
using (FileStream fs = File.Create("data.txt"))
// wrap the stream in the BinaryWriter class, which assists in writing binary files
using (BinaryWriter bw = new BinaryWriter(fs))
{
// create a 32-bit integer
int num = 2019;
// write a 32-bit integer as 4 bytes
bw.Write(num);
}
Первое, что вы заметите, это то, что вы пишете не текстовый файл, а двоичный файл. Расширения файлов являются соглашением и, возможно, говорят нам, что мы должны ожидать найти в файле, но это не истина Евангелия. Я мог бы взять копию Chrome.exe
и переименовать ее в Chrome.txt
, но это не делает ее текстовым файлом.
Какую схему кодирования я должен использовать, чтобы увидеть действие 2019 в текстовом файле?
Когда мы говорим о кодировке, такой как UTF-8, мы говорим о кодировке текста - как преобразовать текст в байты, но мы не имеем дело с текстом в вашем коде, поэтому нет применимого текста формат кодировки для просмотра двоичного файла.
Каковы практические применения BinaryWriter над другими потоковыми адаптерами, такими как StreamWriter?
Позволяет быстро создавать двоичный формат из значений в .NET. Например, вместо того, чтобы вручную преобразовывать значение int
в 4 байта, вы можете вызвать bw.Write(num);
, а также вы можете прочитать эти данные, используя, например, BinaryReader
и br.ReadInt32()
.
Вы не можете испортить последовательность, если вы выполните ReadString (), вы получите забавный персонаж. но кто будет «помнить» или знать последовательности для чтения?
Когда мы говорим о «форматах файлов», мы обычно подразумеваем соглашения, которые мы соблюдаем при чтении файла. Причина, по которой мы можем запустить приложение, прочитать ZIP-файл, прослушать MP3-файл или просмотреть растровое изображение, заключается в том, что используемое нами программное обеспечение написано для понимания этих двоичных форматов.
Если мы возьмем растровое изображение в качестве примера, существует множество документов, описывающих формат файла. Быстрый поиск в Google показывает этот , этот и этот . Вы можете взять любой из них и создать программу для записи файла изображения, используя BinaryWriter
.
Теперь, если бы вы создавали свой собственный формат, вы, вероятно, писали бы писателя и читателя одновременно или, по крайней мере, смотрели бы на код писателя, когда речь идет о написании читателя (если у вас нет спецификации для следуйте, в этом случае вы можете использовать это).
Но то, что я не получаю, это то, что вставленное мной int отображается как забавный символ, вставленная мной строка на самом деле читаема, так почему строка читаема, а не int?
Когда вы звоните Write(string)
, вы на самом деле пишете две вещи: информацию о длине строки и затем пишете саму строку. Для этого BinaryWriter
необходимо преобразовать строку в байты, что она делает для вас за кулисами. Вы можете прочитать об этом здесь и в документации .
Так почему вы можете прочитать строку в вашем файле? Ну, это потому, что текстовая кодировка, используемая здесь, является той же кодировкой, которую вы могли бы использовать для написания текстового файла Ваш текстовый редактор сделает все возможное, чтобы отобразить содержимое всего файла. Это можно увидеть, если перетащить любой текстовый файл (например, Chrome.exe
) в текстовый редактор.
Итак, как вы просматриваете содержимое вашего файла? Ну, вы можете использовать hex hex . Шестнадцатеричный редактор позволяет просматривать и редактировать двоичные файлы. Шестнадцатеричный редактор обычно отображает ваш файл как шестнадцатеричный с одной стороны, а попытка рендерить его как текст с другой.
Итак, представьте, что ваш код такой:
using (FileStream fs = File.Create("data.txt"))
using (BinaryWriter bw = new BinaryWriter(fs))
{
int num = 2019;
bw.Write(num);
bw.Write("hello");
}
Если мы откроем его в шестнадцатеричном редакторе, мы увидим следующее. Обратите внимание, что пробелы между шестнадцатеричными значениями просто для облегчения чтения и не представляют ничего в файле:
E3 07 00 00 05 68 65 6C 6C 6F
Здесь есть три части:
E3 07 00 00 - the hexadecimal expression of little endian 2019
05 - indicating that the string is 5 _bytes_ long
68 65 6C 6C 6F - the hexadecimal representations of each character of the string "hello"
Вы можете прочитать о порядке байтов здесь . Думайте об этом как о том, пишет ли компьютер числа «слева направо» или «справа налево».
Так что, взглянув на значение int, хранящееся выше, мы можем записать его в двоичном формате (1 справа) в виде:
< 00 > < 00 > < 07 > < E3 >
0000 0000 0000 0000 0000 0111 1110 0011
Затем мы можем рассчитать это обратно до 2019 года, ваше первоначальное значение.
Обратите внимание, что информация о длине строки может быть больше одного (согласно этот ответ ).