2010-06-14 5 views
1
이 코드를 사용하여 파일에 StreamWriter 클래스 쓰기 여분의 데이터를 사용하여 이상한 행동을보고 있어요

: 생성 된 파일에 대해, N 각 라인 0에 레코드 집합을 포함 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(); 
     } 
    } 
} 

예 :

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

그러나 생성 된 파일에는 끝에 추가 된 파일부터 더 이상 null 또는 불완전한 레코드가 포함됩니다. 예를 들면 :

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

또는 이것은 또한 또한 StreamWriter 클래스를 사용하는 코드의 분리 된 부분에서 일어나는

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

. 또한 생성 된 파일의 크기는 1024의 배수입니다. 다른 컴퓨터에서도이 동작을 재현 할 수 없으며 환경을 다시 만들려고했습니다. 이전 버전의 응용 프로그램에서는 문제의 메서드에 대해 동일한 코드가 있지만이 동작을 나타내지 않았습니다.

편집 : 추가 코드가 추가되었습니다.

+3

작업 쓰기 코드를 추가하십시오 (예 : 'StreamWriter'에 바이트를 쓰는 방법). – Richard

+0

리처드에 동의합니다. 예외 처리는 모두 부적절합니다. 관련된 모든 코드는''[Write to stream]'안에 있습니다. –

+0

영향을받는 시스템에서 디버거의 코드를 단계별로 실행할 수 있습니까? 영향을받는 시스템에서 보이게 작성하는 로그와 영향을받지 않는 다른 시스템에서 (동일한 입력 데이터에 대해) 다른 점은 무엇입니까? –

답변

3

는 스트림의 끝에 쓰레기에 대해 이야기 할 때 마음에 뛰어 두 가지 시나리오가 있습니다

  1. 이상 쓰기 할 때 절단하지 : 파일을 덮어 미만 데이터를 작성하는 경우, 당신은 잘라야한다 그것. 파일을 열 때이 작업을 수행하는 데 과부하가 걸리거나 theStream.SetLength을 사용할 수 있습니다.
  2. 쓰기 버퍼 패딩; MemoryStream를 사용하는 경우 특히, 가장 일반적인 실수는 - 당신은 과거의 사용 .ToArray().GetBuffer()하지만는 버퍼에서 .Length 바이트를 복사, 또는 사용 (정확한 바이트 수를 얻을 수) (아무것도 중 하나가 있어야합니다 쓰레기)

여기에 "1"이 적용됩니까?

+0

streamWriter = 새 StreamWriter (파일 이름); FileMode.Create를 사용합니다. 이렇게하면 항상 파일이 잘립니다. 이것이 사실 일 수없는 시나리오를 알고 있습니까? –

+0

@zespri에 동의하지 않습니다.doc에서 가져온 StreamWriter (String)의 생성자에서 : 파일이 있으면 덮어 씁니다. 그렇지 않으면 새 파일이 작성됩니다. – Timores

+0

@Timores - 빨리 확인하면 덮어 쓰여지고 (정확하게) 잘린 것으로 나타납니다. 그러니 그 생각을 망쳐 라. –

관련 문제