使用带有标题的Jet Oledb从文本文件中读取(HDR =否)

时间:2015-01-28 12:49:36

标签: csv oledb jet

我有CSV文本文件,我试图从我的代码中读取数据集。如果起始字符是#,则代码读取备用列。

Dataset

以下是我正在使用的代码。

DataSet dsFileRecords = new DataSet();
string selectQuery = "SELECT * FROM " + filename + "";
OleDbConnection fileConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + decryptedFilePath + ";Extended Properties=\"text;HDR=NO;FMT=CSVDelimited;\"");
OleDbDataAdapter dsCmd = new OleDbDataAdapter(selectQuery, fileConnection);
//Fill the DataSet object
dsCmd.Fill(dsFileRecords, "ReconciliationRecords");

更新

我已根据建议的答案更新了我的屏幕截图

enter image description here

输入数据

#Header,TPCCH,LTPTP,TRC,F,2012/06/06 23:59:59,0000000002,0000000003,00.00,00.00,PTP0101011,PTP0101010 
011001001,0110212122,W,W1,2012/06/06 23:59:59,01100110,2L,10.00,,A,,AP09BK4890, 
011001002,0110212123,W,W1,2012/06/06 23:59:59,01100110,2L,10.00,10.00,AD,,AP09BK4890, 
011001003,0110212123,E,E1,2012/06/06 23:59:59,01100110,2L,10.00,10.00,R,012,AP09BK4891, #TRAILER,0000000003

1 个答案:

答案 0 :(得分:3)

Sandeep,hashtag唱歌(#)不是你的问题。

由于您关闭了标头,Jet引擎会将每个列解释为相同的数据类型。在这里说

#Header, 011001001, 011001002, 011001003位于同一列,#header的格式与其他格式不同,因此引擎拒绝该格式。

其余失踪者的情况类似。如果你注意到这个问题并没有发生在第3和第4列,因为它们的格式相同。

要解决此问题,请在连接字符串中将ON更改为HDR=No,然后对第一列进行不同处理,并且不要将其用于数据,从而转变标题HDR=Yes类型识别目的。

为了让您对正在发生的事情有所了解,我已经编写了一个小的控制台应用程序来复制这种情况。

var file = new FileInfo("C:\\TextFile.txt");

OleDbConnection fileConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" + file.DirectoryName + "\";Extended Properties='text;HDR=No;FMT=Delimited(,)';");
string selectQuery = "SELECT * FROM " + file.Name;

using (var cmd = new OleDbCommand(selectQuery, fileConnection))
{
    fileConnection.Open();
    OleDbDataAdapter dsCmd = new OleDbDataAdapter(selectQuery, fileConnection);
    //Fill the DataSet object
    DataSet dsFileRecords = new DataSet();
    dsCmd.Fill(dsFileRecords, "ReconciliationRecords");

    foreach (DataTable dsFileRecord in dsFileRecords.Tables)
    {
        foreach (DataRow row in dsFileRecord.Rows)
        {
            foreach (var item in row.ItemArray)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine( "\r\n" );
        }
    }
}

Console.ReadLine();

我要在这里测试的是 TextFile.txt

的内容

如果内容是

#FName, LName, Phone 
Hank, Donald, 0202
Walter, W, 0203
Jimmy, Jones, 0201

输出是,

#FName
LName


Hank
Donald
202

Walter
W
203

Jimmy
Jones
201

如果您注意到我在第一个标题之前添加了#以清除暂停。现在您可以看到标题 电话 缺失,因为它在同一列中的所有行后面的值都有一个数值。

现在检查一下。我的TextFile.txt内容为,

#FName, LName, Phone 
Hank, Donald, 0202
Walter, W, 0203
Jimmy, Jones, 0201

将控制台应用中的输出显示为

#FName
LName
1111

Hank
Donald
202

Walter
W
203

Jimmy
Jones
201

那有多好?!我为值1111替换的值Phone很好。 :)

转动标题On并将此块添加到第一个Foreach内和rows Foreach之前的代码中,然后打印标题并打印如下所示排序,

foreach (DataTable dsFileRecord in dsFileRecords.Tables)
{
    // Added foreach statement. 
    foreach (DataColumn column in dsFileRecord.Columns)
    {
        Console.WriteLine(column.ColumnName.ToString());
    }

    Console.WriteLine("\r\n");

    foreach (DataRow row in dsFileRecord.Rows)
    {
        foreach (var item in row.ItemArray)
        {
            Console.WriteLine(item.ToString());
        }
        Console.WriteLine("\r\n");
    }
}

,输出为,

#FName
LName
Phone

Hank
Donald
202

Walter
W
203

Jimmy
Jones
201

瞧!

<强>更新

#Header#Trailer不是您数据的一部分,因此需要在处理之前将其删除。一个小正则表达式可以做到这一点(但如果你不知道正则表达式(Regular Expression Language),这可能看起来像黑魔法。)

这是需要在开始时修改的代码

var file = new FileInfo("C:\\RealTextFile.txt");

// Regex to remove the "#Header" and "#Trailer".
// The modigied txt file will be saved with the "_" prefix.
File.WriteAllLines(file.DirectoryName + "\\_" + file.Name,
    File.ReadAllLines(file.FullName).Select(content =>
        Regex.Replace(content, @".*(?>#Header,)|#TRAILER.+", string.Empty)
    ));

file = new FileInfo(file.DirectoryName + "\\_" + file.Name);


OleDbConnection fileConnection = ...