c # - данные "потеряны" при использовании двоичных данных в строке? - PullRequest
2 голосов
/ 28 октября 2008

Я пытался прочитать файл JPG, используя метод StreamReader class 'ReadToEnd(), который возвращает строку.

По какой-то причине, когда я записываю эту строку в файл, она не открывается.

Что-то теряется при чтении данных в строку?

Ответы [ 9 ]

25 голосов
/ 28 октября 2008

Строки предназначены для текста данных. Они не для двоичных данных - если вы используете их таким образом, вы потеряете данные (вы можете использовать кодировки, которые не потеряют данные, если вам повезет, но есть тонкие проблемы, которые все еще остаются сделать это действительно плохой идеей.)

Если вы на самом деле имеете дело с файлом, самый простой способ прочитать все это - вызвать File.ReadAllBytes . Если вам приходится иметь дело с произвольным потоком, посмотрите на «Создание байтового массива из потока» .

5 голосов
/ 29 октября 2008

Всегда помните, текстовые данные - это двоичные данные , но двоичные данные не текст данные .

5 голосов
/ 28 октября 2008

Как знают все настоящие программисты, единственной полезной структурой данных является массив. Строки, списки, структуры, наборы - все это особые случаи массивов, и их можно так же легко обрабатывать, не путая язык программирования со всевозможными сложностями. Хуже всего в причудливых типах данных является то, что вы должны их объявлять, а в настоящих языках программирования, как мы все знаем, существует неявная типизация, основанная на первой букве имени (шести символов) переменной.

Кроме того, настоящий Программист может писать программы на Фортране на любом языке.


Тот, кто это сделал, явно не имеет ни чувства юмора, ни знания фольклора. Вышесказанное взято из очень известного письма 1983 года редактору Datamation Эд Пета из Tektronix. Письмо называется Настоящие программисты не используют Паскаль .

4 голосов
/ 28 октября 2008

String предназначен для хранения символов Юникода; не двоичный Для двоичного файла используйте byte[] или Stream. Или Image и т. Д. Для более специализированной обработки изображений.

Несмотря на название, StreamReader на самом деле является специализированным TextReader - т.е. это TextReader, который читает из Stream. Изображения не являются текстом, так что это неправильный вариант.

1 голос
/ 28 октября 2008

К сожалению, существует серьезная проблема с именами классов в пространстве имен System.IO. StreamReader предназначен для чтения \ записи из \ в текстовые файлы. Вы должны использовать FileStream для бинарных файлов, как @goodwill предложил

0 голосов
/ 08 июня 2012

В строках по умолчанию используется кодировка Unicode, Unicode использует символ NUL в качестве управляющего символа, двойной NUL используется для завершения, один NUL используется для представления символа ASCII перед ним.

По этой причине двоичные данные не могут быть загружены в строку.

0 голосов
/ 29 октября 2008

Я заметил, что никто не ответил на реальные вопросы.

Что-то теряется при чтении данных в строку?

Файл JPEG содержит изображение, а не слова. Этот bicture имеет двоичное представление в виде последовательности байтов. Некоторые из этих байтов имеют значение 0x00, также представленное как NUL. В строке байт, содержащий это значение, интерпретируется как маркировка конца строки. Данные после конца строки обрабатываются как неиспользуемый буфер и игнорируются.

Когда вы записываете строку в файл, ничего после первого NUL не включается. В результате файл не является полным двоичным изображением и отклоняется логикой проверки программного обеспечения, пытающегося интерпретировать его как JPEG.

Таким образом, данные, как правило, теряются при загрузке строки с нетекстовыми данными. Проблема в том, что вы фактически сделали неверный тип, но ни компилятор, ни среда выполнения не остановили вас, и в результате произошло повреждение данных.

Для чего это действительно хорошо?

Несколько вещей. Как уже говорили другие, строки предназначены для содержания текста. В .NET строки поддерживают кодировки, отличные от простого старого ASCII. Существует также обширная поддержка для манипулирования текстом. Посмотрите спецификаторы формата в справке для наглядного примера манипуляции со строками.

Почему строки C # используют NUL для конца строки?

Это устаревшая вещь. NUL не очень хорош для всего остального, и это упрощает сортировку строк в управляемом коде и из него. BSTR делает то же самое по тем же причинам.

0 голосов
/ 28 октября 2008

Строки используются для представления текста. Они хорошо представляют текст. На самом деле это очень хорошо, поскольку они поддерживают Unicode и защищают вас от всевозможных типичных ошибок обработки строк.

Они не очень хорошо представляют двоичные данные, потому что это не то, для чего они предназначены. Как вы упоминаете, байтовый массив гораздо лучше для этого.

Дело не в том, что один лучше другого, а в том, что он подходит для цели и понимает, когда выбирать один или другой. Текст = строка, двоичный файл = байтовый массив или поток.

0 голосов
/ 28 октября 2008

Вы просто не можете сделать это таким образом .... Вместо этого используйте FileStream.

Вы не можете использовать строку для чтения бинарных файлов, насколько я знаю, некоторые символы не пробиваются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...