如果文件已损坏,OleDbConnection 将锁定 Excel xls 文件
OleDbConnection locks Excel xls file if the file is corrupted
我有一个遗留代码将 Excel (*.xls) 导入我们的数据库,然后在处理后将文件移动到特定目录。
代码工作正常,除了在一种情况下,当文件损坏时(即使 MS Excel 也无法打开它)!在这种情况下发生的是 System.AccessViolationException
在打开连接时抛出!
代码如下所示:
string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", filePath);
OleDbConnection connection = new OleDbConnection(connectionString);
try
{
connection.ConnectionString = connectionString;
connection.Open(); //<<<--- exception throws here
//file processing
}
catch (Exception e)
{
//exception handling
}
finally
{
connection.Close();
connection.Dispose();
connection = null;
GC.Collect();
}
这是异常的详细信息...
System.AccessViolationException was caught
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=System.Data
StackTrace:
at System.Data.Common.UnsafeNativeMethods.IDBInitializeInitialize.Invoke(IntPtr pThis)
at System.Data.OleDb.DataSourceWrapper.InitializeAndCreateSession(OleDbConnectionString constr, SessionWrapper& sessionWrapper)
at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.OleDb.OleDbConnection.Open()
如您所见,我正在捕获此异常并对其进行处理,然后当代码尝试将文件移动到另一个目录时,出现以下异常:
System.IO.IOException occurred
Message=The process cannot access the file because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.Move(String sourceFileName, String destFileName)
我尝试使用另一个库,例如LinqToExcel,但发现它在内部使用与我相同的实现,那么它有同样的问题!
我也尝试在连接关闭后 运行 垃圾收集器(如您在上面的代码中看到的那样),但遇到了同样的问题!
有什么想法吗?
我现在有同样的问题,我唯一的解决方案是使用 Microsoft.Office.Interop.Excel 读取 excel 文件并设置 MsoFileValidationMode = msoFileValidationSkip;
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xl工作簿;
System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
**xlApp.FileValidation = MsoFileValidationMode.msoFileValidationSkip;**
xlWorkbook = xlApp.Workbooks.Open(@"C:\my file.xls");
Excel.Sheets xlWorksheet = xlWorkbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)xlWorksheet.get_Item(3);
for (int i = 1; i <= 10; i++)
{
Excel.Range range = worksheet.get_Range("A" + i.ToString(), "B" + i.ToString()); ; //UsedRange;
System.Array myvalues = (System.Array)range.Cells.Value2;
string[] strArray = ConvertToStringArray(myvalues);
foreach (string item in strArray)
{
MessageBox.Show(item);
}
}
...效果不错
我试图解决问题中的主要解决方案,但没有结果:(
我什至检查了 .NET Framework 代码并且可以在代码中的某处看到文件句柄,但不幸的是未能调试代码:(
我尝试反编译 .NET Framework 代码但也失败了:(
终于。它结束了我应该使用另一个解决方案,并且由于依赖于生产机器中 MS Office 的存在不是一个选项,我去了 ExcelDataReader,一个将 *.xls 文件读取为二进制流的开源库,并且这是最终代码的样子:
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream, true))
{
excelReader.IsFirstRowAsColumnNames = true;
var excelFileDataSet = excelReader.AsDataSet();
var sheetDataTable = excelFileDataSet.Tables["sheetName"];
//other file processing code...
}
}
这个解决方案对我有用!
我有一个遗留代码将 Excel (*.xls) 导入我们的数据库,然后在处理后将文件移动到特定目录。
代码工作正常,除了在一种情况下,当文件损坏时(即使 MS Excel 也无法打开它)!在这种情况下发生的是 System.AccessViolationException
在打开连接时抛出!
代码如下所示:
string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""", filePath);
OleDbConnection connection = new OleDbConnection(connectionString);
try
{
connection.ConnectionString = connectionString;
connection.Open(); //<<<--- exception throws here
//file processing
}
catch (Exception e)
{
//exception handling
}
finally
{
connection.Close();
connection.Dispose();
connection = null;
GC.Collect();
}
这是异常的详细信息...
System.AccessViolationException was caught
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=System.Data
StackTrace:
at System.Data.Common.UnsafeNativeMethods.IDBInitializeInitialize.Invoke(IntPtr pThis)
at System.Data.OleDb.DataSourceWrapper.InitializeAndCreateSession(OleDbConnectionString constr, SessionWrapper& sessionWrapper)
at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.OleDb.OleDbConnection.Open()
如您所见,我正在捕获此异常并对其进行处理,然后当代码尝试将文件移动到另一个目录时,出现以下异常:
System.IO.IOException occurred
Message=The process cannot access the file because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.Move(String sourceFileName, String destFileName)
我尝试使用另一个库,例如LinqToExcel,但发现它在内部使用与我相同的实现,那么它有同样的问题!
我也尝试在连接关闭后 运行 垃圾收集器(如您在上面的代码中看到的那样),但遇到了同样的问题!
有什么想法吗?
我现在有同样的问题,我唯一的解决方案是使用 Microsoft.Office.Interop.Excel 读取 excel 文件并设置 MsoFileValidationMode = msoFileValidationSkip;
Excel.Application xlApp = new Excel.Application(); Excel.Workbook xl工作簿;
System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
**xlApp.FileValidation = MsoFileValidationMode.msoFileValidationSkip;**
xlWorkbook = xlApp.Workbooks.Open(@"C:\my file.xls");
Excel.Sheets xlWorksheet = xlWorkbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)xlWorksheet.get_Item(3);
for (int i = 1; i <= 10; i++)
{
Excel.Range range = worksheet.get_Range("A" + i.ToString(), "B" + i.ToString()); ; //UsedRange;
System.Array myvalues = (System.Array)range.Cells.Value2;
string[] strArray = ConvertToStringArray(myvalues);
foreach (string item in strArray)
{
MessageBox.Show(item);
}
}
...效果不错
我试图解决问题中的主要解决方案,但没有结果:(
我什至检查了 .NET Framework 代码并且可以在代码中的某处看到文件句柄,但不幸的是未能调试代码:(
我尝试反编译 .NET Framework 代码但也失败了:(
终于。它结束了我应该使用另一个解决方案,并且由于依赖于生产机器中 MS Office 的存在不是一个选项,我去了 ExcelDataReader,一个将 *.xls 文件读取为二进制流的开源库,并且这是最终代码的样子:
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream, true))
{
excelReader.IsFirstRowAsColumnNames = true;
var excelFileDataSet = excelReader.AsDataSet();
var sheetDataTable = excelFileDataSet.Tables["sheetName"];
//other file processing code...
}
}
这个解决方案对我有用!