2011-06-07 180 views
4

我需要解析一個utf8編碼的csv。轉換後,我剛看到問題出現在BOM()字符處。我無法使用utf8編碼創建避免BOM的csv,因爲即使它是utf8編碼,也需要解析它。如何從UTF 8編碼的csv中刪除BOM(?)字符?

中的任何一個,請告訴我,我怎樣才能從CSV使用C#.NET刪除BOM()字符..

更新:我已經加入我的代碼讀取因爲即時通訊的CSV頭在文件的開頭獲取BOM。

string CSVConnectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + ConfigurationSettings.AppSettings["CSVFolder"].ToString() + ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"; 

     using (OdbcConnection Connection = new OdbcConnection(CSVConnectionString)) 
     { 
      List<string> CSVHeaders = new List<string>(); 

      string SelectQuery = string.Format(@"SELECT TOP 1 * FROM [{0}]", CSVFileName); 

      OdbcCommand Command = new OdbcCommand(SelectQuery, Connection); 

      Connection.Open(); 

      OdbcDataReader Reader = Command.ExecuteReader(System.Data.CommandBehavior.CloseConnection); 

      int ColumnCount = Reader.FieldCount; 

      for (int column = 0; column < ColumnCount; column++) 
      { 
       CSVHeaders.Add(Reader.GetName(column)); 
      } 

      return CSVHeaders; 
     } 
+1

您不需要刪除BOM,只需要正確讀取文件。你的代碼是什麼樣的? – 2011-06-07 05:38:30

+0

@ Jeff,我編輯了我的問題,代碼爲 – Harun 2011-06-07 05:57:22

+0

我無法正確讀取文件,因爲它是作爲上載到Solr的一部分讀取的。如果您真的想在您的代碼片段中使用csvtext驅動程序,則可以使用FileReader和FileWriter組合來創建一個Path,我需要發送沒有BOM的文件,如Simon的新UTF8Encoding(false) – 2012-09-06 15:12:01

回答

2

這裏是做了這樣的功能:

public static void SaveAsUTF8WithoutByteOrderMark(string fileName) 
    { 
     SaveAsUTF8WithoutByteOrderMark(fileName, null); 
    } 

    public static void SaveAsUTF8WithoutByteOrderMark(string fileName, Encoding encoding) 
    { 
     if (fileName == null) 
      throw new ArgumentNullException("fileName"); 

     if (encoding == null) 
     { 
      encoding = Encoding.Default; 
     } 

     File.WriteAllText(fileName, File.ReadAllText(fileName, encoding), new UTF8Encoding(false)); 
    } 
+0

如果文件沒有編碼或用其他編碼進行編碼,這是否合適?我的意思是,我應該只用於utf8編碼的文件。 – Harun 2011-06-07 06:55:22

+0

我不會推薦這種方式來處理大文件。 – svick 2011-06-07 06:57:59

+0

@哈倫 - 不,這個函數只適用於UTF8輸入文件,或者輸入文件只包含ASCII字符。 – 2011-06-07 07:02:54

4

實際上,C#可以讀取包含BOM的UTF-8編碼文件。這是您使用的破損的CSV文本驅動程序,實際上是導致問題的原因。我建議使用this answer的其他CSV閱讀解決方案之一。

+0

。 GetTempFilename()不含BOM的文件副本 – eFloh 2011-06-07 06:54:32

+0

這很好用...感謝您的回答。如果直到現在我還沒有完成,我肯定會使用它。我無法在使用新的外部DLL後重新運行我的完整測試用例。 – Harun 2011-06-07 07:38:18

+0

@Harun:不確定「新的外部DLL」是什麼意思......你的意思是你不能爲這個項目添加新的引用?在這種情況下,也許你可以使用[Microsoft.VisualBasic.FileIO.TextFieldParser](http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx),因爲它是.NET Framework。 – 2011-06-07 15:36:10

1

而是改變馬(使用其他.csv驅動程序)或通過拉自己的車(更改編碼)有助於給定的馬,你應該告訴馬(標準的ODBC文本驅動程序),它需要通過增加一個schema.ini文件就知道做工作:

[withbomgood.txt] 
Format=TabDelimited 
ColNameHeader=True 
CharacterSet=65001 
Col1=FrsColümn CHAR 

定義withbomgood.txt的格式:

FrsColümn 
whätever 

這是withbombad.txt的精確副本;這兩個文件有一個BOM:

FrsColümn 
whätever 

如果你現在打電話稍微修改副本

static void Harun00(string CSVFileName) 
{ 
    string CSVFilePath = @"E:\trials\SoTrials\answers\6260911\data"; 
    string CSVConnectionString = 
     "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + 
     CSVFilePath + 
     ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"; 

    using (OdbcConnection Connection = new OdbcConnection(CSVConnectionString)) 
    { 
     List<string> CSVHeaders = new List<string>(); 

     string SelectQuery = string.Format(@"SELECT TOP 1 * FROM [{0}]", CSVFileName); 

     OdbcCommand Command = new OdbcCommand(SelectQuery, Connection); 

     Connection.Open(); 

     OdbcDataReader Reader = Command.ExecuteReader(System.Data.CommandBehavior.CloseConnection); 

     int ColumnCount = Reader.FieldCount; 

     for (int column = 0; column < ColumnCount; column++) 
     { 
      CSVHeaders.Add(Reader.GetName(column)); 
     } 

     Console.WriteLine(CSVHeaders[0]); 
    } 
} 
代碼的

兩次:

static void Main(string[] args) 
{ 
    Harun00("withbombad.txt"); 
    Harun00("withbomgood.txt"); 
} 

你:

FrsColümn 
FrsColümn 
Press any key to continue . . . 

證明司機會讀取UT F8與BOM文件正確,如果遵循以下規則,則不需要任何其他ADO:在schema.ini文件中定義您的csv表。

+0

雖然神祕,但這個答案實際上對我有效。爲了澄清,我使用Col#= {ColumnName} {Type}格式指定了所有列,不同之處在於我爲Type指定了第一列,即使在我的情況下它確實是一個Long。參考[http://msdn.microsoft.com/en-us/library/windows/desktop/ms709353(v=vs.85).aspx]MSDN。 – Vic 2012-10-23 23:29:35