【问题标题】:Reading from text file using Jet Oledb with headers off (HDR=No)使用 Jet Oledb 读取文本文件并关闭标题 (HDR=No)
【发布时间】:2015-01-28 12:49:36
【问题描述】:

我有一个 CSV 文本文件,我试图将它从我的代码中读取到数据集中。如果起始字符是 #,则代码读取交替列。

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

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");

更新

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

输入数据

#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

【问题讨论】:

    标签: csv oledb jet


    【解决方案1】:

    Sandeep,主题标签唱歌 (#) 不是您的问题。

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

    #Header, 011001001, 011001002, 011001003 在同一列中,#header 的格式与其他格式不同,因此引擎会拒绝它。

    其余失踪者的情况类似。如果您注意到此问题不会发生在第 3 列和第 4 列,因为它们的格式相同。

    要解决此问题,请通过将连接字符串中的 HDR=No 更改为 HDR=Yes 来转动您的标题 ON,第一列将被区别对待,并且不会用于数据类型识别目的。

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

    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
    

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

    现在检查一下。我的 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
    

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

    打开标题 On 并将此块添加到您的代码中的第一个 Foreachrows 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 = ...
    

    【讨论】:

    • 我认为这会有所帮助,但它没有读取浮动量值.. 检查新的屏幕截图。
    • 没关系,我已经给你修好了。让我看看你提到的浮点数有什么问题。 @sandeep
    • @sandeep,我看了你的截图,老实说不知道发生了什么。你能像我添加截图的方式更新你的问题,这次包括文本文件的原始内容,甚至是其中的一部分吗?
    • #Header,TPCCH,LTPTP,TRC,F,2012/06/06 23:59:59,0000000002,0000000003,00.00,00.00,PTP0101011,PTP0101010 011001001,01102122122,W /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) #header&#trailer 不是您的数据的一部分,因此应该删除。检查我对答案的更新。 2)您有重复的标题名称00.0000.00。这在任何数据库系统 AFAIK 中都不会发生,因为它将创建两个相同名称的字段。 3)您的标题中包含点 .,它们会被转换为 #。有关 2&3 的解决方案,请在此处查看我的答案 stackoverflow.com/a/28227665/1316651
    猜你喜欢
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2012-11-26
    相关资源
    最近更新 更多