3

このコードを使用して余分なデータをファイルに書き込む 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 の倍数です。他のマシンではこの動作を再現できず、環境を再作成しようとしました。アプリケーションの以前のバージョンでは、問題のメソッドのコードが同じであるにもかかわらず、この動作は見られませんでした。

編集:余分なコードを追加しました。

4

1 に答える 1

5

ストリームの最後にあるガベージについて話すとき、2 つのシナリオが思い浮かびます。

  1. 上書き時に切り詰めない: ファイルを上書きしても書き込むデータが少ない場合は、切り詰める必要があります。ファイルを開くときにこれを行うためのオーバーロードがあります。または、theStream.SetLength.
  2. バッファパディングの書き込み; 特に、最も一般的な間違いは使用するときMemoryStreamです-使用する(正しいバイト数を取得するために)使用するだけでバッファからバイトをコピーする必要があります(それを過ぎたものはゴミです).ToArray().GetBuffer() .Length

ここに「1」が当てはまると思いますか?

于 2010-06-14T10:50:05.970 に答える