Почему StreamReader.ReadLine () возвращает значение для однострочного файла без перевода строки? - PullRequest
4 голосов
/ 10 августа 2010

Я хочу добавить два текстовых файла вместе.

У меня есть один файл с переводом каретки на конец строки.Наблюдайте файл A, который составляет 28 байт.

это строка в файле \ n

, тогда у меня есть другой файл, такой же, без новой строки.Наблюдайте файл B размером 26 байт.

это строка в файле

Я хочу добавить тот же файл к себе (файл A к A и файлB к B) и сравните число байтов.

Однако при использовании StreamReader.ReadLine() для файла A я получаю возвращаемое значение, но MSDN говорит:

Строка определяется какпоследовательность символов, за которой следует перевод строки ("\ n"), возврат каретки ("\ r") или возврат каретки, за которым сразу следует перевод строки ("\ r \ n").Возвращаемая строка не содержит завершающего возврата каретки или перевода строки.Возвращаемое значение равно нулю, если достигнут конец входного потока.

Однако в файле нет crlf.

Как можно безопасно добавить эти файлы без добавлениядополнительный разрыв строки в конце?Например, StreamWriter.WriteLine() добавит дополнительный разрыв строки в файл A, когда я этого не хочу.Каким был бы идеальный подход?

Ответы [ 4 ]

3 голосов
/ 10 августа 2010

Вы получите null, только если позвоните ReadLine в конце потока . В противном случае вы получите все данные вплоть до или a CRLF или конца потока.

Если вы пытаетесь выполнить побайтное дублирование (и сравнение), вам лучше читать либо символы (используя StreamReader / StreamWriter, как вы используете сейчас), либо байты (используя просто используя класс Stream), используя обычные функции Read и Write вместо ReadLine и WriteLine.

Вы также можете просто прочитать все содержимое файла, используя ReadToEnd, а затем записать его, вызвав Write (не WriteLine), хотя это не практично, если файл большой.

string data;

using(StreamReader reader = new StreamReader(path))
{
    data = reader.ReadToEnd();
}

using(StreamWriter writer = new StreamWriter(path, true))
{
    writer.Write(data);
}
2 голосов
/ 10 августа 2010

StreamReader и StreamWriter (производные от TextReader и TextWriter) не подходят для ситуаций, требующих точной формы двоичных данных.Они являются абстракциями высокого уровня файла, который состоит из байтов, а не текста или строк.Фактически, вы можете не только получить разное количество новых строк, но в зависимости от среды вы можете записать терминатор строки, отличный от ожидаемого CR / LF.другой.На самом деле это довольно просто.

var bytes = File.ReadAllBytes(pathIn);
var stream = File.Open(pathOut, FileMode.Append);
stream.Write(bytes, 0, bytes.Length);
stream.Close();

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

using (var streamIn = File.Open(pathIn, FileMode.Read))
using (var streamOut = File.Open(pathOut, FileMode.Append)) {

    var bytes = new byte[BLOCK_SIZE];

    int count;
    while ((count=streamIn.Read(bytes, 0, bytes.Length)) > 0) {
        streamOut.Write(bytes, 0, count);
    }

}

Также стоит отметить, что вышеприведенный код можно заменить на Stream.CopyTo , который является новым в .NET 4.

2 голосов
/ 10 августа 2010

Вы можете использовать StreamWriter.Write вместо WriteLine, чтобы избежать лишних ошибок.

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

0 голосов
/ 10 августа 2010

Ну, это действительно зависит от причин вашей реализации (Почему вы читаете это построчно и пишете обратно построчно?) Вы можете просто использовать StreamWriter.Write(string) и вывести весь текст, который у вас есть сохранены, методы WriteLine() названы как таковые, потому что они добавляют новую строку.

Метод TextWriter.WriteLine (строка)
Записывает строку, за которой следует символ конца строки, в текстовый поток.

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