Vb.net .net文件随机访问记录锁定
摘要:在.net中锁定随机访问文件中的记录时,我们无法访问文件中锁定记录之前的记录 为了演示这个问题,我编写了两个简单的程序,一个打开并锁定一条记录,另一个尝试通读 结果是,当在第一个程序中锁定10条记录中的9条时,我们可以读取记录1和2,但不能读取更多!我们的期望(这是我们使用VB6的经验)是,您应该能够读取除锁定的记录之外的所有记录 有人见过这个问题吗?我在做什么奇怪的事吗?有工作吗 演示代码: 程序1创建/打开/锁定Vb.net .net文件随机访问记录锁定,vb.net,vb6,locking,Vb.net,Vb6,Locking,摘要:在.net中锁定随机访问文件中的记录时,我们无法访问文件中锁定记录之前的记录 为了演示这个问题,我编写了两个简单的程序,一个打开并锁定一条记录,另一个尝试通读 结果是,当在第一个程序中锁定10条记录中的9条时,我们可以读取记录1和2,但不能读取更多!我们的期望(这是我们使用VB6的经验)是,您应该能够读取除锁定的记录之外的所有记录 有人见过这个问题吗?我在做什么奇怪的事吗?有工作吗 演示代码: 程序1创建/打开/锁定 Sub Main() Dim FileName As Stri
Sub Main()
Dim FileName As String = "test.a"
Dim ListofName() As String = {"Name1", "Name2", "Name3", "Name4",
"Name5", "Name6", "Name7", "Name8", "Name9", "Name10"}
Try
Dim FileNumber1 As Integer = FreeFile()
FileOpen(FileNumber1, FileName, OpenMode.Random,
OpenAccess.ReadWrite, OpenShare.Shared, 600)
FileGet(FileNumber1, People, 1)
'Create File if needs be
If People.Name = "" Then
For A = 1 To 10
People.Name = ListofName(A - 1)
FilePut(FileNumber1, People, A)
Next
End If
'Lock the recoard we want for testing
Lock(FileNumber1, 9)
Catch ex As Exception
FileClose()
End Try
FileClose()
End Sub
_
打开程序2并尝试阅读
Sub Main()
Dim FileName As String = "C:\**Location of first program file**\test.a"
Try
Dim FileNumber1 As Integer = FreeFile()
FileOpen(FileNumber1, FileName, OpenMode.Random,
OpenAccess.ReadWrite, OpenShare.Shared, 600)
FileGet(FileNumber1, People, 2)
'See how much of the file we can read
For A = 1 To 10
FileGet(FileNumber1, People, A)
System.Diagnostics.Debug.WriteLine(People.Name.ToString)
Next
Catch ex As Exception
FileClose()
End Try
FileClose()
End Sub
编辑0.1:我们发现,单个记录在文件中锁定得越深,在锁定的记录之前,无法访问的字节/记录就越多。谢谢大家的评论 在MSDN上发布了相同的问题并设法得到了答案 因此,结论是,对于.net,如果使用FileGet或(例如System.IO.BinaryReader.ReadDouble()),读卡器不仅可以读取所需内容,还可以缓冲内容,这意味着文件中前面的锁定记录被命中,导致读取失败 但是当使用System.IO.FileStream.Read()并精确指定所需的字节数时,不会创建缓冲区,从而使您能够读取文件中除锁定记录以外的所有记录 代码示例:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)>
Structure Person
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=600)>
<VBFixedString(600)>
Dim name As String
End Structure
. . .
Using fs = New FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, Marshal.SizeOf(People))
For A = 1 To 10
Try
Console.WriteLine("Trying " & A & "...")
Dim b() As Byte
ReDim b(Marshal.SizeOf(People) - 1)
fs.Seek((A - 1) * Marshal.SizeOf(People), SeekOrigin.Begin)
fs.Read(b, 0, b.Length)
Dim h = GCHandle.Alloc(b, GCHandleType.Pinned)
People = Marshal.PtrToStructure(Of Person)(h.AddrOfPinnedObject())
h.Free()
Console.WriteLine(People.name.Trim())
Catch ex As Exception
Console.WriteLine("ERROR " & A & " " & ex.Message)
End Try
Next
End Using
结构人
将名称设置为字符串
端部结构
. . .
使用fs=newfilestream(文件名、FileMode.Open、FileAccess.ReadWrite、FileShare.ReadWrite、Marshal.SizeOf(人))
对于A=1到10
尝试
Console.WriteLine(“尝试”&A&“…”)
Dim b()作为字节
雷迪姆b(元帅人数-1)
财政司司长Seek((A-1)*元帅SizeOf(人民),SeekOrigin.Begin)
fs.Read(b,0,b.长度)
尺寸h=GCHandle.Alloc(b,GCHandleType.pinted)
People=Marshal.ptrto结构(个人的)(h.addrofPindedObject())
h、 免费的
Console.WriteLine(People.name.Trim())
特例
Console.WriteLine(“错误”&A&&ex.Message)
结束尝试
下一个
终端使用
urg。。。开始使用System.IO。无论如何,文件并非总是立即“完全”写入。您需要关闭或刷新流。为什么使用vb6标记?vb6=vb.net可能是兼容性库中的一个bug;文档化行为用于Lock
仅锁定单个记录。人员对象的大小是多少?是600字节吗?@the_lotus谢谢,我相信我们已经用System.IO进行了测试,我们也遇到了同样的问题(当锁定一条记录时,前面的几条记录无法被其他单独的进程访问),如果您愿意,我也可以发布演示代码来显示。至于“完全”编写,我将在下周回到办公室时对此进行调查,但由于上述两个独立的代码位是在不同的开发实例中运行的,我不确定情况是否如此。返回的错误是一个建议锁定的错误,而不是类似的文件结束错误。