使用 VB.NET 从 Filemaker 的 BLOB(容器)字段读取大文件 (>5MB)
我正在尝试使用 Filemaker 自己的 ODBC 驱动程序从 FileMaker 11 容器字段读取二进制文件。我能够将文件写入数据库,并且效果很好。手动检索它们工作正常,文件看起来正常并且没有损坏。
然而,当使用 VB.NET 检索它们时,如果文件大小约为 > 5MB,我收到以下“无法捕获”错误(是的,没错,我无法“Try Catch End Try”,它只会崩溃):
System.AccessViolationException was unhandled
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
检索 <5MB 的文件工作正常。
以下是代码及其崩溃位置:
Using cn2 As New Odbc.OdbcConnection(G_AppSettings.ODBC_FileMaker("xxx", "xxx", "xxx")) ' Establish ODBC connection to FileMaker DB
cn2.Open()
cmd = New OdbcCommand("SELECT DocumentName, GetAs(DocumentContainer, 'FILE') FROM Documents WHERE DocumentID = " & id, cn2)
myReader = cmd.ExecuteReader()
If myReader.Read() Then
' get the name of the file
If Not myReader.IsDBNull(0) Then
TempDoc.FileName = myReader.GetValue(0)
End If
' check for problems:
If TempDoc.FileName = "" Then
MsgBox("Error: file name not specified. Could not open file.")
Exit Sub
End If
If tempDir = "" Then
MsgBox("Error: can't find local temp directory. Could not open file.")
Exit Sub
End If
' -----------------------------
' SAVE FILE IN TEMP WINDOWS DIR
' -----------------------------
fs = New FileStream(tempDir & "\" & TempDoc.FileName, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
' Read bytes into outbyte() and retain the number of bytes returned.
Dim ds1 = myReader.GetDataTypeName(1)
Dim ds2 = myReader.GetFieldType(1)
Dim bytesRead = myReader.GetBytes(1, 0, outbyte, 0, bufferSize) < - CRASHES HERE
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)
' Continue reading and writing while there are bytes beyond the size of the buffer.
Do While retval = bufferSize
bw.Write(outbyte)
bw.Flush()
' Reposition the start index to the end of the last buffer and fill the buffer.
startIndex += bufferSize
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)
Loop
' Write the remaining buffer.
bw.Write(outbyte, 0, retval - 1)
bw.Flush()
' Close the output file.
bw.Close()
fs.Close()
End If
cn2.Close()
End Using
我使用的是 Windows XP/7 客户端,并将数据库托管在 FileMaker Advanced Server 11 上。
任何有关此问题的帮助都将非常有用!
I'm trying to read a binary file from a FileMaker 11 container field using Filemaker's own ODBC driver. I was able to write files to the database and this works fine. retrieving them manually works fine and the files look OK and are not corupted.
However when retreiving them using VB.NET, and if the file size is approx > 5MB, I get the following "uncatchable" error (yes thats right, I cant "Try Catch End Try", it just crashes):
System.AccessViolationException was unhandled
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Retrieving a file that is <5MB works fine.
Here is the code and where it crashes:
Using cn2 As New Odbc.OdbcConnection(G_AppSettings.ODBC_FileMaker("xxx", "xxx", "xxx")) ' Establish ODBC connection to FileMaker DB
cn2.Open()
cmd = New OdbcCommand("SELECT DocumentName, GetAs(DocumentContainer, 'FILE') FROM Documents WHERE DocumentID = " & id, cn2)
myReader = cmd.ExecuteReader()
If myReader.Read() Then
' get the name of the file
If Not myReader.IsDBNull(0) Then
TempDoc.FileName = myReader.GetValue(0)
End If
' check for problems:
If TempDoc.FileName = "" Then
MsgBox("Error: file name not specified. Could not open file.")
Exit Sub
End If
If tempDir = "" Then
MsgBox("Error: can't find local temp directory. Could not open file.")
Exit Sub
End If
' -----------------------------
' SAVE FILE IN TEMP WINDOWS DIR
' -----------------------------
fs = New FileStream(tempDir & "\" & TempDoc.FileName, FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
' Read bytes into outbyte() and retain the number of bytes returned.
Dim ds1 = myReader.GetDataTypeName(1)
Dim ds2 = myReader.GetFieldType(1)
Dim bytesRead = myReader.GetBytes(1, 0, outbyte, 0, bufferSize) < - CRASHES HERE
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)
' Continue reading and writing while there are bytes beyond the size of the buffer.
Do While retval = bufferSize
bw.Write(outbyte)
bw.Flush()
' Reposition the start index to the end of the last buffer and fill the buffer.
startIndex += bufferSize
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize)
Loop
' Write the remaining buffer.
bw.Write(outbyte, 0, retval - 1)
bw.Flush()
' Close the output file.
bw.Close()
fs.Close()
End If
cn2.Close()
End Using
I am using Windows XP/7 clients and hosting the database on FileMaker Advanced Server 11.
Any help on this would be great!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过多次尝试和错误,我终于回答了我自己的问题。上面发布的所有代码都可以正常工作,除了我忘记指定 OdbcDataReader 的行为
这一行:
应该是:
似乎这导致了我遇到的问题,其中某些文件可以正确打开,而其他人则不会。希望这对某人有帮助!蒂姆.
After lots of trial and error, I have finally answered my own question. All of the code posted above works correctly, except I forgot to specify the behaviour for the OdbcDataReader
This line:
Should be:
It seems that this was causing the problems I was having where some files would open correctly while others wouldn't. Hope this helps someone! Tim.