2012-10-12 70 views
3

我在我的項目中使用CSVReader來讀取windows服務中的.csv文件。 我們將.csv文件傳遞給CSVReader來處理文件,它工作正常。 但最近我們決定將csv文件保存到數據庫表並從那裏讀取它。當用戶提交csv文件進行處理時,我們的aspx頁面將讀取csv文件 並將其轉換爲字節數組並將其保存到數據庫。 並且該服務將讀取表並拾取字節數組並將其轉換爲FileStream。 此流傳遞給CSVReader以供進一步工作。 現在它爲最後一列的最後一列拋出錯誤。 它僅在保存並從數據庫中讀取後纔會發生。 我收到以下錯誤。 不知道如何解決這個問題。CSVReader在最後一列最後一列拋出錯誤

「的CSV似乎是接近記錄‘9’字段‘3在位置‘494’當前原始數據。:’腐敗

聽到的是代碼轉換 文件以字節數組.....

try 
{ 
    fs = new FileStream(filepath, FileMode.Open); 
    fsbuffer = new byte[fs.Length]; 
    fs.Read(fsbuffer, 0, (int)fs.Length); 
} 

從數據庫讀取到字節數組......

myobject.FileByteArray = ObjectToByteArray(row); 

public byte[] ObjectToByteArray(DataRow row) 
     { 
      if (row["fileBytearray"] == null) 
       return null; 
      try 
      { 
       BinaryFormatter bf = new BinaryFormatter(); 
       System.IO.MemoryStream ms = new System.IO.MemoryStream(); 

       bf.Serialize(ms, row["fileBytearray"]); 
       return ms.ToArray(); 
      } 
    } 

Stream fileStream = new MemoryStream(myobject.FileByteArray) 
using (CsvReader csv = 
         new CsvReader(new StreamReader(fileStream, System.Text.Encoding.UTF7), hasHeader, ',')) 
+0

什麼是你在存儲數據到列類型? – dash

+0

列類型是varbinary(max) – Henry

+0

所以它不是截斷。當您創建StreamReader時,您正在使用'UTF7'編碼。你確定這是該文件最初編碼的方式嗎?你嘗試過'ASCII'或'UTF8'嗎? – dash

回答

2

我一直無法重現你的問題,所以代替,如,沒有看到保存和負荷beginni NG要結束了,我會建議試圖檢索如下:

public MemoryStream LoadReportData(int rowId) 
{ 

    MemoryStream stream = new MemoryStream(); 

    using (BinaryWriter writer = new BinaryWriter(stream)) 
    { 

    using (DbConnection connection = db.CreateConnection()) 
    { 
     DbCommand selectCommand = "SELECT CSVData FROM YourTable WHERE Id = @rowId"; 

     selectCommand.Connection = connection; 

     db.AddInParameter(selectCommand, "@rowId", DbType.Int32, rowId); 
     connection.Open(); 

     using (IDataReader reader = selectCommand.ExecuteReader(CommandBehavior.SequentialAccess)) 
     { 

     while (reader.Read()) 
     { 

      int startIndex = 0; 
      int bufferSize = 8192; 

      byte[] buffer = new byte[bufferSize]; 

      long retVal = reader.GetBytes(0, startIndex, buffer, 0, bufferSize); 

      while (retVal == bufferSize) 
      { 

      writer.Write(buffer); 
      writer.Flush(); 

      startIndex += bufferSize; 
      retVal = reader.GetBytes(0, startIndex, buffer, 0, bufferSize); 

      } 

      writer.Write(buffer, 0, (int)retVal); 
     } 

     } 

    } 
    } 

    return stream; 

} 

你需要更換的SelectCommand SQL和參數與任何SQL您使用的返回數據。

此方法使用SqlDataReader順序從相應的行(由ROWID在我的例子確定),並應避免在途中不會被截斷的問題出列(在我的例子稱爲CSVData)讀取的字節(它可能是你的DataTable對象只返回第一個n字節)。 MemoryStream對象可用於將CSV文件重新保存到文件系統進行測試,或直接進入CSVReader。

如果您可以發佈您的Save方法(您實際上將數據持久存儲到數據庫),那麼我們也可以檢查以確保截斷不在那裏發生。

我現在可以提出的另一個建議涉及到將文件加載到byte陣列中。如果你要加載的文件一氣呵成,那麼你可以簡單地取代:

try 
{ 
    fs = new FileStream(filepath, FileMode.Open); 
    fsbuffer = new byte[fs.Length]; 
    fs.Read(fsbuffer, 0, (int)fs.Length); 
} 

byte[] fileBytes = File.ReadAllBytes(filepath); 
+0

感謝您的詳細解釋並給我代碼。真的很感激你的時間。它解決了這個問題。 – Henry