потоковый писатель не записывает усеченный текст в файл в C # - PullRequest
0 голосов
/ 16 июня 2011

У меня странная проблема.Я получаю поток текста от клиента TCP и записываю его в файл.Поток заполнен не полностью, поэтому при преобразовании его в строку незаполненные части массива байтов преобразуются в \ 0, так что в итоге я получаю

str = "blah foo bar \0\0\0\0\0...";

, поэтому я сделал

str = str.trim('\0');

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

StreamWriter sw = new StreamWriter("c:\\a\\ta.txt");
while (true)
{
    try
    {
        NetworkStream ns = tc.GetStream();
        byte[] instream = new byte[tc.ReceiveBufferSize];
        Thread.Sleep(2500);
        ns.Read(instream, 0, tc.ReceiveBufferSize);
        string decodedData = string.Empty;
        decodedData = System.Text.Encoding.ASCII.GetString(instream);
        decodedData = decodedData.Trim('\0');
        //string a = "dfdsfdsfdsfdsf";
        //string b = a.Trim('\0');

        try
        {
            sw.Write(decodedData);
            //MessageBox.Show(decodedData);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

Может кто-нибудь объяснить мне, почему это так и как я могу решить эту проблему.

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

Ответы [ 4 ]

4 голосов
/ 16 июня 2011

Здесь есть три проблемы.

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

Чтобы исправить это, измените код следующим образом:

int actuallyRead = ns.Read(instream, 0, tc.ReceiveBufferSize);
string decodedData = Encoding.ASCII.GetString(instream, 0, actuallyRead);

Во-вторых, вам нужно закрыть поток, чтобы он очистил его содержимое. Лучший способ сделать это - обернуть его в using блок:

using (StreamWriter sw = new StreamWriter("c:\\a\\ta.txt"))
{
    ... rest of your code here
}

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

int actuallyRead = ns.Read(instream, 0, tc.ReceiveBufferSize);
if (actuallyRead == 0)
    break;
string decodedData = Encoding.ASCII.GetString(instream, 0, actuallyRead);
3 голосов
/ 16 июня 2011

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

Вам следует также посмотреть значение, возвращаемое из Stream.Read, и создать только строку, используя ту часть буфера, которая фактически была прочитана.1008 *

Наконец, неясно, как вы ожидаете, что это завершится, учитывая, что у вас есть цикл while(true).Вы в настоящее время собираетесь прекратить действие только тогда, когда получите исключение.Вы, вероятно, должны прекратить работу, если ns.Read вернет 0.

1 голос
/ 16 июня 2011

Попробуйте это:

decodedData = new string(decodedData.ToCharArray());

IIRC, строковой конструктор обрежет завершающие нулевые терминаторы.

0 голосов
/ 16 июня 2011

ты пробовал ...

 decodedData = decodedData.Trim(@"\0");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...