2011-03-21 47 views
1

我想一個CSV加載到數據表中使用這樣的:故障解析的Unicode CSV文件

class CSVReader 
{ 
    public System.Data.DataTable GetDataTable(string strFileName) 
    { 
     System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection 
     (
     "Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + 
     "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\"" 
     ); 
     conn.Open(); 
     string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]"; 
     System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn); 
     System.Data.DataSet ds = new System.Data.DataSet("CSV File"); 
     adapter.Fill(ds); 
     return ds.Tables[0]; 
    } 
} 

它正常工作,一個一個CSV,而不是其他。這是不正確加載該文件的片段: enter image description here

它只是加載「T」作爲第一個列名,其他一切都是空/空。我試圖手動看第一行以

Using (StreamReader x = new StreamReader(fileName) { string firstline x = x.ReadLine(); } 

和等效File.ReadAllLines和參考陣列的「0」條目(文件[0])。

兩者都簡單地將「T」作爲「第一行」返回,超出這個範圍的任何內容都是空白的。任何想法爲什麼它只能看到CSV中的第一個字符而沒有其他的東西?

編輯:第一行看起來像這樣:

術語(複數),OBJECTID,FILE,PATH,命中計數

第二行看起來像這樣:

「(test)」,「172911」,「16369318」,「Item001.E01/Partition 1/NONAME [NTFS]/[unallocated space]/13621367/16369318」,「4」

編輯2: 我切換了lib鏈接的人(CVSReader),它似乎已經消除了很多痛苦。我試圖編碼UTF-8的文件用記事本++和它得到更遠沿,直到它到達:

LumenWorks.Framework.IO.Csv.MalformedCsvException了未處理 消息=的CSV似乎是接近記錄腐敗'位置'2601'處的'1373'字段'3。當前原始數據:'32 /System.ServiceModel/06d6eab93282d2b136a377bd50b7c5a9/System.ServiceModel.ni.dll","11「 」(vc)「,」40656「,」Adobe AIR Application Installer.swf「,」Item001.E01 /分區1/NONAME [NTFS]/[root]/Program Files/Common Files/Adob​​e AIR/Versions/1.0/Adob​​e AIR Application Installer.swf「,」11「 」(vc)「,」503322「,」䄳䆷䞫䄦䠥」, 「Item001.E01 /分區1/NONAME [NTFS]/[根] /WINDOWS/Installer/520ae67.msp/䄳䆷䞫䄦䠥」, 「11」

我猜如果我按照原來的方式離開文件,原始編碼,它處理得不好/不正確,我不想讓用戶必須打開文件並保存它作爲ASCII/UTF-16,因爲它是~90mb。我一直試圖谷歌周圍,但大多數人說.NET可以處理任何編碼。

看來文件輸出爲UCS-2 LE(我認爲它是UTF-16,對嗎?)。我「米困惑,爲什麼CVSReader/StreamReader的服用問題。

診斷,但不能完全解決

當我通過‘字符集= Unicode的’追加到我的OldeDB函數的字符串,它似乎爲USC工作-2LE/Unicode編碼我寧願使用CSVReader自定義庫,但它似乎使用TextReader(據我所知可以不處理Unicode)。

http://www.codeproject.com/KB/database/CsvReader.aspx

下面的代碼將無法正常工作。它不會拋出一個錯誤,但它似乎停滯了,甚至在自己的線程:

糟糕的代碼爲USC2/Unicode的:

   using (CsvReader csv = new CsvReader(
          new StreamReader(kwfile, Encoding.Unicode), true)) 
      { 
       csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty; 
       keywordHits.Load(csv); 
      } 

工作,但不是首選的解決方案:

 public System.Data.DataTable GetDataTable(string strFileName) 
    { 
     System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection 
     (
     "Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + 
     "; Extended Properties = \"Text;characterset=Unicode;HDR=YES;FMT=Delimited\"" 
     ); 
     conn.Open(); 
     string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]"; 
     System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn); 
     System.Data.DataSet ds = new System.Data.DataSet("CSV File"); 
     adapter.Fill(ds); 
     return ds.Tables[0]; 
    } 

我已經在CSVReader可選的第三個參數試了一下爲好,並沒有什麼區別。該程序「工作」通過使用CSVReader類加載一個CSV,但必須使用Unicode CSV上的OldeDB。很明顯,使用帶有Encoding.Unicode參數的StreamReader可以工作,但是我不得不重新發明解析出可能格式錯誤的條目。有什麼想法嗎?或者,這是我可以做的最好的,無需重寫CSVReader?

+0

你能與虛擬二號線某處發佈文件? – 2011-03-21 16:52:40

+1

@jonathan:它是零。期。零upvotes和零「接受」。你在看什麼? – 2011-03-21 16:56:34

+0

第二行看起來像這樣 「(測試)」, 「172911」, 「16369318」, 「Item001.E01 /分區1/NONAME [NTFS]/[未分配空間] /16369318分之13621367」, 「4」 – Jai 2011-03-21 16:56:56

回答

4

一種遠出手,但也許你的文件是使用UTF-16編碼。該文件中的字節會是這樣的:

T <NUL> E <NUL> ... 

嘗試使用打開文件:

0x54 0x00 0x45 0x00 ... 

使用UTF-8編碼(默認爲StreamReader)將產生以下字符閱讀這些字節二元編輯器。如果編碼是意外的,那麼在文本編輯器中將其打開並使用適合您的編碼進行保存(ASCII或UTF-8是很好的候選)。

+0

這似乎是它。我編輯了我的帖子。感謝讓我走上正軌,儘管我仍然有點困惑,但至少我知道發生了什麼問題。 – Jai 2011-03-21 18:39:10

0

從一開始就是這個片段?我發現使用OleDb閱讀器時,它會將架構基於第一行,這樣如果後續行具有更多列,則其他列將被忽略。

我停止使用它因爲這個原因。如果你想要輕量級的東西,我在this answer.有一個全功能的CsvReader。

0

當你的文件是UTF-16編碼,嘗試指定的StreamReader的和/或CVS閱讀器代碼的編碼。 .NET中的默認編碼是UTF-8,它將產生Martin Liversage所述的字符。 對於我不知道的CVS類,StreamReader有一個重載的新StreamReader(路徑,Encoding.UTF16)。

+0

它看起來像CVS閱讀器使用TextReader獲取傳遞給它的StreamReameder。我嘗試將一個UTF-16覆蓋傳遞給流讀取器,但是從我可以告訴/讀取的情況來看,TextWriter僅採用系統的默認編碼(UTF-8?)。如果我想使用這個CVSReader,我看不出來了嗎? – Jai 2011-03-22 13:35:11

+0

對不起,正如我已經說過的,我不知道您使用的CSVReader。但是TextWriter類也可以使用不同的語句,看一下StreamWriter的子類! – eFloh 2011-03-23 12:31:42