我正在尝试使用以下方法将 CSV 文件加载到 DataTable 中:
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 文件中运行良好,但在另一个文件中却不行。以下是未正确加载的文件片段:
它只是将“T”加载为第一列名称,其他所有内容均为空白/空值。我尝试用
手动查看第一行Using (StreamReader x = new StreamReader(fileName) { string firstline x = x.ReadLine(); }
和等效的 File.ReadAllLines 并引用了数组的“0”条目 (file[0])。
两者都只是将“T”作为“第一行”返回,除此之外的任何内容都是空白的。为什么它只看到 CSV 中的第一个字符而没有其他任何想法?
编辑:第一行看起来像这样:
TERM(s),OBJECTID,FILE,PATH,HIT COUNT
第二行是这样的:
"(test)","172911","16369318","Item001.E01/Partition 1/NONAME [NTFS]/[unallocated space]/13621367/16369318","4"
编辑 2: 我切换了某人链接的库 (CVSReader),它似乎减轻了很多痛苦。我尝试使用 Notepad++ 以 UTF-8 编码文件,它继续前进,直到到达:
LumenWorks.Framework.IO.Csv.MalformedCsvException was unhandled Message=The CSV appears to be corrupt near record '1373' field '3 at position '2601'. Current raw data : '32/System.ServiceModel/06d6eab93282d2b136a377bd50b7c5a9/System.ServiceModel.ni.dll","11" "(vc)","40656","Adobe AIR Application Installer.swf","Item001.E01/Partition 1/NONAME [NTFS]/[root]/Program Files/Common Files/Adobe AIR/Versions/1.0/Adobe AIR Application Installer.swf","11" "(vc)","503322","䄳䆷䞫䄦䠥","Item001.E01/Partition 1/NONAME [NTFS]/[root]/WINDOWS/Installer/520ae67.msp/䄳䆷䞫䄦䠥","11"
我猜它对 UTF-8 编码中的外来字符有疑问。如果我按原样保留文件,原始编码,它处理得很差/不正确。我不想让用户必须打开文件并将其保存为 ASCII/UTF-16,因为它是 ~90mb。我一直在尝试四处搜索,但大多数人都说 .NET 可以处理任何编码。
文件似乎输出为 UCS-2 LE(我认为是 UTF-16,对吧?)。我很困惑为什么 CVSReader/StreamReader 会出现问题。
诊断但未完全解决
当我在我的 OldeDB 函数上传递附加到字符串的“characterset=Unicode”时,它似乎适用于 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。显然,将 StreamReader 与 Encoding.Unicode 参数一起使用是可行的,但我必须重新发明轮子来解析可能格式错误的条目。有什么想法吗?或者这是我在不重写 CSVReader 的情况下能做的最好的事情吗?
最佳答案
远景,但也许您的文件是使用 UTF-16 编码的。文件中的字节如下所示:
0x54 0x00 0x45 0x00 ...
使用 UTF-8 编码(StreamReader
的默认设置)读取这些字节将产生以下字符:
T <NUL> E <NUL> ...
尝试使用二进制编辑器打开您的文件。如果编码是意外的,则在文本编辑器中打开它并使用适合您的编码保存它(ASCII 或 UTF-8 是不错的选择)。
关于c# - 无法解析 Unicode CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5380806/