2010-04-03 7 views
8

У меня есть методStreamReader.ReadToEnd() возвращает пустую строку

private static String DecompressAndDecode(byte[] data) 
{ 
    GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); 
    StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8); 
    String result = decompressed.ReadToEnd(); 
    return result; 
} 

У меня есть некоторый текст с gzip'нутым в качестве входных данных и результат должен быть строковым представлением этого текста. Проблема в том, что метод возвращает пустую строку. Меня озадачивает то, что когда я перехожу через метод в режиме отладки и доставляю оператор return, переменная результата - пустая строка, но если я создам часы для выражения decpressed.ReadToEnd(), он вернет мне текст. То, что я ожидаю в этой точке, - это переменная результата, содержащая текст и выражение decpressed.ReadToEnd(), оценивающее пустую строку. (Переоценка выражения распакованного.ReadToEnd() возвращает пустую строку, как ожидалось).

@Edit: Я обнаружил, что в моем случае ReadToEnd() возвращает текст на второй вызов возвращающегося пустые строки по первому зову и после второго звонка.

Должно быть что-то очевидное, я здесь отсутствует.

+0

Действительно ли кодировка UTF8? –

+0

Да, это UTF8. – axk

ответ

21

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

Запустите следующий код до ReadToEnd, чтобы установить указатель на начало. someStream.Seek(0, SeekOrigin.Begin)

+0

Это решило проблему для меня – Aaronontheweb

+0

Нет функции поиска участника для streamReader. – stackptr

+0

@stackptr you нужно использовать его в потоке, который вы подаете в ваш streamReader –

1

«Должно быть что-то очевидное, что я здесь отсутствует». - может быть, и я тоже ;-)
Начнем с небольшого автономного примера и посмотрим, где он отличается от вашего фактического кода.

class SOTest 
{ 
    private static String DecompressAndDecode(byte[] data) 
    { 
    GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); 
    StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8); 
    String result = decompressed.ReadToEnd(); 
    return result; 
    } 

    private static byte[] foo(string data) 
    { 
    MemoryStream dest = new MemoryStream(); 
    using (GZipStream compressor = new GZipStream(dest, CompressionMode.Compress)) 
    { 
     using (StreamWriter sw = new StreamWriter(compressor)) 
     { 
     sw.Write(data); 
     } 
    } 
    return dest.GetBuffer(); 
    } 


    static void Main() 
    { 
    System.Console.WriteLine(
     DecompressAndDecode(foo("Mary had a little lamb.")) 
    ); 
    return; 
    } 
} 

печатает Mary had a little lamb.

+0

Спасибо за вашу помощь! Ваш пример работает. Единственное различие в моем случае я получаю данные из базы данных SQL с помощью SqlDataReader, и текст довольно длинный и имеет некоторые символы, отличные от ascii. Я обнаружил, что в моем случае_ ReadToEnd возвращает текст во втором вызове. – axk

+0

Это происходит только с более длинными данными или вы можете уменьшить объем данных (переданных в DecompressAndDecode (byte []) для целей отладки? – VolkerK

1

Создайте свою собственную функцию. Это займет путь в качестве параметра:

static string read(string path) 
    { 
     StreamReader sr = new StreamReader(@path); 
     string txt = ""; 
     while (!sr.EndOfStream) { 
      txt += sr.ReadLine() + "\n"; 
     } 
     sr.Close(); 
     return txt; 
    } 

Затем вызовите его вместо вызова ReadToEnd(). Я тестировал его, и это сработало.

Смежные вопросы