StreamWriter добавляет случайные данные - PullRequest
3 голосов
/ 14 июня 2010

Я наблюдаю странное поведение, когда класс StreamWriter записывает дополнительные данные в файл с использованием этого кода:

public void WriteToCSV(string filename)
{
    StreamWriter streamWriter = null;
    try
    {
        streamWriter = new StreamWriter(filename);
        Log.Info("Writing CSV report header information ... ");
        streamWriter.WriteLine("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", ((int)CSVRecordType.Header).ToString("D2", CultureInfo.CurrentCulture), m_InputFilename, m_LoadStartDate, m_LoadEndDate);

        int recordCount = 0;

        if (SummarySection)
        {
            Log.Info("Writing CSV report summary section ... ");
            foreach (KeyValuePair<KeyValuePair<LoadStatus, string>, CategoryResult> categoryResult in m_DataLoadResult.DataLoadResults)
             {
                streamWriter.WriteLine("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", ((int)CSVRecordType.Summary).ToString("D2", CultureInfo.CurrentCulture), categoryResult.Value.StatusString, categoryResult.Value.Count.ToString(CultureInfo.CurrentCulture), categoryResult.Value.Category);
                recordCount++;
             }
        }

        Log.Info("Writing CSV report cases section ... ");
        foreach (KeyValuePair<KeyValuePair<LoadStatus, string>, CategoryResult> categoryResult in m_DataLoadResult.DataLoadResults)
        {
            foreach (CaseLoadResult result in categoryResult.Value.CaseLoadResults)
            {
                if ((LoadStatus.Success == result.Status && SuccessCases) ||
                    (LoadStatus.Warnings == result.Status && WarningCases) ||
                    (LoadStatus.Failure == result.Status && FailureCases) ||
                    (LoadStatus.NotProcessed == result.Status && NotProcessedCases))
                {
                    streamWriter.Write("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"", ((int)CSVRecordType.Result).ToString("D2", CultureInfo.CurrentCulture), result.Status, result.UniqueId, result.Category, result.ClassicReference);
                    if (RawResponse)
                    {
                        streamWriter.Write(",\"{0}\"", result.ResponseXml);
                    }
                    streamWriter.WriteLine();
                    recordCount++;
                }
            }
        }

        streamWriter.WriteLine("\"{0}\",\"{1}\"", ((int)CSVRecordType.Count).ToString("D2", CultureInfo.CurrentCulture), recordCount);

        Log.Info("CSV report written to '{0}'", fileName);
    }
    catch (IOException execption)
    {
        string errorMessage = string.Format(CultureInfo.CurrentCulture, "Unable to write XML report to '{0}'", fileName);
        Log.Error(errorMessage);
        Log.Error(exception.Message);
        throw new MyException(errorMessage, exception);
    }
    finally
    {
        if (null != streamWriter)
        {
            streamWriter.Close();
        }
    }
}

Созданный файл содержит набор записей в каждой строке от 0 до N, например:

[Record Zero]
[Record One]
...
[Record N]

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

[Record Zero]
[Record One]
...
[Record N]
[Lots of nulls]

или

[Record Zero]
[Record One]
...
[Record N]
[Half complete records]

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

РЕДАКТИРОВАТЬ: добавлен дополнительный код.

1 Ответ

5 голосов
/ 14 июня 2010

Есть два сценария, которые приходят на ум при разговоре о мусоре в конце потока:

  1. не обрезается при перезаписи: если вы перезаписываете файл, но пишете меньше данных, тодолжен усечь это.При открытии файла происходит перегрузка, или вы можете использовать theStream.SetLength.
  2. заполнение буфера записи;в частности, наиболее распространенная ошибка возникает при использовании MemoryStream - вы должны либо использовать .ToArray() (для получения правильного количества байтов), или использовать .GetBuffer() но только скопировать .Length байт из буфера (что-нибудь, кроме мусора)

Я предполагаю, что здесь применяется "1"?

...