2016-10-26 4 views
-1

У меня есть два блока кода, которые я пытался использовать для чтения данных из файлового потока в C#. Моя общая цель здесь состоит в том, чтобы попытаться прочитать каждую строку текста в списке строк, но все они считываются в одну строку (при открытии с возможностью чтения + записи вместе) ...Почему FileStream иногда игнорирует невидимые символы?

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

StreamReader sr = null; 
StreamWriter sw = null; 
FileStream fs = null; 
List<string> content = new List<string>(); 
List<string> actual = new List<string>(); 
string line = string.Empty; 

// first, open up the file for reading 
fs = File.OpenRead(path); 
sr = new StreamReader(fs); 

// read-in the entire file line-by-line 
while(!string.IsNullOrEmpty((line = sr.ReadLine()))) 
{ 
    content.Add(line); 
} 
sr.Close(); 

Теперь вот блок кода, который игнорирует все пробельные символы (т.е. line-feed, возврат каретки) и читает весь файл в одной строке.

StreamReader sr = null; 
StreamWriter sw = null; 
FileStream fs = null; 
List<string> content = new List<string>(); 
List<string> actual = new List<string>(); 
string line = string.Empty; 

// first, open up the file for reading/writing 
fs = File.Open(path, FileMode.Open); 
sr = new StreamReader(fs); 

// read-in the entire file line-by-line 
while(!string.IsNullOrEmpty((line = sr.ReadLine()))) 
{ 
    content.Add(line); 
} 
sr.Close(); 

Почему Open вызывают все данные для чтения в виде одной строки, и OpenRead работает правильно (читает данные как несколько строк)?

UPDATE 1

меня попросили представить текст файла, который воспроизводит проблему. Так вот ниже (убедитесь, что CR + LF в конце каждой строки !! Я не уверен, что получит вставили здесь!)

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 
;$$$$$$$$$                $$$$$$$ 
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 
; 
; 
; 

UPDATE 2

Точный блок кода, который воспроизводит проблему (используя текст выше для файла). В этом случае я действительно вижу проблему БЕЗ попыток Open и только с использованием OpenRead.

StreamReader sr = null; 
StreamWriter sw = null; 
FileStream fs = null; 
List<string> content = new List<string>(); 
List<string> actual = new List<string>(); 
string line = string.Empty; 

try 
{ 
    // first, open up the file for reading/writing 
    fs = File.OpenRead(path); 
    sr = new StreamReader(fs); 

    // read-in the entire file line-by-line 
    while(!string.IsNullOrEmpty((line = sr.ReadLine()))) 
    { 
     content.Add(line); 
    } 
    sr.Close(); 

    // now, erase the contents of the file 
    File.WriteAllText(path, string.Empty); 

    // make sure that the contents of the file have been erased 
    fs = File.OpenRead(path); 
    sr = new StreamReader(fs); 
    if (!string.IsNullOrEmpty(line = sr.ReadLine())) 
    { 
     Trace.WriteLine("Failed: Could not erase the contents of the file."); 
     Assert.Fail(); 
    } 
    else 
    { 
     Trace.WriteLine("Passed: Successfully erased the contents of the file."); 
    } 

    // now, attempt to over-write the contents of the file 
    fs.Close(); 
    fs = File.OpenWrite(path); 
    sw = new StreamWriter(fs); 
    foreach(var l in content) 
    { 
     sw.Write(l); 
    } 

    // read back the over-written contents of the file 
    fs.Close(); 
    fs = File.OpenRead(path); 
    sr = new StreamReader(fs); 
    while (!string.IsNullOrEmpty((line = sr.ReadLine()))) 
    { 
     actual.Add(line); 
    } 

    // make sure the contents of the file are correct 
    if(content.SequenceEqual(actual)) 
    { 
     Trace.WriteLine("Passed: The contents that were over-written are correct!"); 
    } 
    else 
    { 
     Trace.WriteLine("Failed: The contents that were over-written are not correct!"); 
    } 
} 
finally 
{ 
    // close out all the streams 
    fs.Close(); 

    // finish-up with a message 
    Trace.WriteLine("Finished running the overwrite-file test."); 
} 
+1

FileStream не игнорирует «невидимых» символов, это не волнует персонажей. 'StreamReader' - это класс, который читает текст и обрабатывает символы новой строки, но он * не игнорирует их. Является ли файл * одинаковым * в обоих случаях? Является ли содержимое * тем же? Можете ли вы опубликовать код, который воспроизводит проблему? –

+0

@PanagiotisKanavos Очевидно, у меня должна быть проблема X Y. Да, я уверен, спасибо, спасибо за вопрос. Надеюсь, это поможет выяснить, что здесь происходит. – Snoopy

+0

Я не могу воспроизвести проблему с этим кодом в .NET 4.6.2 в Windows.Оба фрагмента кода дают линии индивидуально вплоть до первой пустой строки, как и следовало ожидать, поскольку оба файла «File.Open» и «File.OpenRead» являются простыми оболочками вокруг конструктора «FileStream». –

ответ

0

Ваш новый файл, сгенерированный

foreach(var l in content) 
{ 
    sw.Write(l); 
} 

не содержит конца-строки символов, так как конец-строки символов не включены в content.

Как @DaveKidder указывает на this thread over here, spec for StreamReader.ReadLine конкретно говорит, что итоговая строка не включает конец строки.

Когда вы

while(!string.IsNullOrEmpty((line = sr.ReadLine()))) 
{ 
    content.Add(line); 
} 
sr.Close(); 

Вы теряете конец строки символов.

+0

Во второй раз я пытаюсь прочитать это, это правда, но в первый раз я прочитал его в примере, который он работает. – Snoopy

+0

@StevieV В первый раз, когда вы его прочитали, в строке 15 по строке 17 вы читаете файл, который был создан с концевыми символами вне вашего приложения. Во второй раз, когда вы его читаете, в строке 50 по строке 53 вы читаете файл, созданный без концевых символов вашим приложением. Это не имеет ничего общего с методами чтения, когда вы впервые читаете data1, во второй раз, когда вы читаете data2, а data1 имеет разные байты, чем data2. После строки 11 вы можете сохранить массив байтов, затем сделать то же самое после строки 48 и изучить их, они будут разными наборами байтов. – Nomenator