[英]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 =新的Excel.Application(); Excel.Workbook xlWorkbook;
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...
}
}
這個解決方案對我有用!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.