代码之家  ›  专栏  ›  技术社区  ›  John Weldon user3678248

64位模式不支持OLEDB?

  •  14
  • John Weldon user3678248  · 技术社区  · 15 年前

    我一直在使用Microsoft.jet.oledb.4.0和Microsoft.ace.oledb.12.0来读取.csv、.xls和.xlsx文件。

    我刚发现这两种技术都不支持本地64位模式!

    我有两个问题:

    1. 支持的方法是什么 以编程方式读取.csv、.xls和 .xlsx文件处于64位模式。我只是 在任何地方都找不到答案。

    2. 如果我看不到这三个文件 类型,什么是最好的阅读方式 在64位的.csv文件中 环境?

    笔记:

    • 我用的是.NET(3.5p1)
    • 这是一个收缩包装应用程序;重新分发是一个 关键因素。

    更新:

    我可以使用corflags强制应用程序以32位模式运行,这是可行的,但不可取。

    7 回复  |  直到 12 年前
        1
  •  8
  •   JP Alioto    15 年前

    这里有一个关于该做什么的讨论 about deprecated MDAC . 恐怕答案不是很令人满意…

    这些新的或改装的喷气式飞机 应用程序可以继续使用Jet 打算使用微软 Office 2003及更早版本的文件(.mdb) 和.xls)对于非主数据 存储。然而,对于这些 应用程序,您应该计划 从Jet迁移到2007 Office 系统驱动程序。您可以下载 2007 Office System Driver,其中 允许您读写 在任一办公室预先存在的文件 2003(.mdb和.xls)或Office 2007(*.accdb、*.xlsm、*.xlsx和 *.xlsb)文件格式。重要信息请阅读2007 Office System最终用户 特定用途许可协议 局限性。

    注意:SQL Server应用程序也可以 访问2007 Office System,以及 之前,来自SQL Server的文件 异构数据连接和 集成服务能力 好吧,通过2007年的办公系统 驱动程序。另外,64位SQL 服务器应用程序可以访问 32位Jet和2007 Office System 使用32位SQL Server的文件 64位上的集成服务(SSIS) 窗户。

        2
  •  4
  •   Stefan Rusek    15 年前

    主要问题是JetDBMS是一个32位的库,它被加载到调用过程中,所以在64位模式下,您将永远无法直接从应用程序中使用Jet。正如蒂姆提到的,您可以编写自己的csv解析器,但是由于这是一个收缩包装应用程序,所以您需要能够处理更广泛格式的东西。幸运的是,有很多方法可以说32位应用程序,所以你仍然可以用一个技巧。

    我会写一个被标记为只在32位模式下运行的小exe。这个exe将接受一个命令行参数,其中包含要读取的文件名和要写入的临时文件名。我将使用jet加载csv/xls,然后将数据放入数组中,并使用XML序列化程序将数据写入临时文件。

    然后,当我需要加载/转换csv/xls文件时,我将执行以下操作:

    object[][] ConvertFile(string csvOrXlsFile)
    {
        var output = System.IO.Path.GetTempFileName();
        try
        {
            var startinfo = new System.Diagnostics.ProcessStartInfo("convert.exe",
                string.Format("\"{0}\" \"{1}\"", csvOrXlsFile, output));
    
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = startinfo;
    
            proc.Start();
            proc.WaitForExit();
    
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(object[][]));
            using (var reader = System.IO.File.OpenText(output))
                return (object[][])serializer.Deserialize(reader);
        }
        finally
        {
            if (System.IO.File.Exists(output))
                System.IO.File.Delete(output);
        }
    }
    
        3
  •  4
  •   Christopher G. Lewis    15 年前

    你可以试试 FileHelpers 用于平面文件分析的库。效果非常好。

        4
  •  4
  •   Joe Erickson    15 年前

    SpreadsheetGear for .NET 可以读写.csv/.xls/.xlsx工作簿(和 more )并支持64位.NET 2.0+。电子表格可以免费分发与收缩包装应用。

    您没有指定您的应用程序是winforms还是asp.net,但spreadsheetgear可以与两者一起使用。您可以看到实时的ASP.NET(C&vb)示例 here ,了解WinForms示例 here 下载免费试用版 here 如果你想自己试试。

    免责声明:我拥有SpreadsheetGear LLC

        5
  •  3
  •   user334370    14 年前

    对于任何可能遇到此问题的人(对我自己来说,如果我将来遇到同样的问题,并且不记得解决方案),这是一篇信息性的帖子。 这有点晦涩,但给我带来了几个小时的压力,所以也许它能帮助别人…很抱歉,如果重复(找不到)或否决(有些没有最新和最棒的奢侈)。

    如果您试图使用Jet 4.0访问基于x64的服务器上的MS Excel文档(或其他数据文件),您将发现不支持这种组合。

    唯一的解决方案是允许IIS在Windows64上运行32位应用程序并安装受支持的DB提供程序。

    您需要安装驱动程序,即作为网桥的用于ODBC(msdasql)的64位OLEDB提供程序: “用于ODBC的Microsoft OLE DB Provider(msdasql)是一种技术,它允许基于OLEDB和ADO(内部使用OLEDB)构建的应用程序通过ODBC驱动程序访问数据源。msdasql是一个连接到ODBC的OLEDB提供程序,而不是数据库。MSDASQL随Windows操作系统一起提供,Windows Server 2008和Windows Vista SP1是第一个包含64位版本技术的Windows版本。” 此处下载: http://www.microsoft.com/downloads/details.aspx?FamilyID=000364db-5e8b-44a8-b9be-ca44d18b059b&displaylang=en

    这一切都很好,但我遇到了两件让我挠头(和压力)的事情: 1)您需要在IIS Web服务扩展中允许32位ASP.NET-读取 http://www.textcontrol.com/blog/permalink/2006082101 有关启用32位应用程序和IIS Web服务扩展安装程序的说明。 2)如果使用的是IIS x64下的任何注册表项,则会在注册表中添加一个新节点-wow6432节点-需要将x64下使用的任何相关项移动/复制到该节点中。 例如,我们在hclm\software\customkey中存储了一个数据密钥,在启用32位时该密钥不再可用。我们在wow6432节点下重新创建了密钥,一切都很好。

        6
  •  3
  •   Justin Dearing    12 年前

    你可以使用 Microsoft Access Database Engine 2010 Redistributable 要读取和写入csv、xls访问等,每个驱动程序都有32位和64位版本。

        7
  •  1
  •   Tim Jarvis    15 年前

    实际上,我认为Linq是解决这个问题的最佳方案。

    比如……

    IEnumerable<MyObj> ObjList = GetObjList(yourCSVFileNAme);
    
    var qry = from o in ObjList
              where o.MyField == Something
              select o;
    

    你的getobjlist方法看起来像

    Public IEnumerable<MyObj> GetObjList(string filename)
    {
      // Obvioulsly you would have some actual validation and error handling
      foreach(string line in File.ReadAllLines(filename))
      {
        string[] fields = line.Split(new char[]{','});
        MyObj obj = new MyObj();
        obj.Field = fields[0];
        obj.AnotherField = int32.Parse(fields[1]);
        yield return obj;
      }
    }