Vb.net .net文件随机访问记录锁定

Vb.net .net文件随机访问记录锁定,vb.net,vb6,locking,Vb.net,Vb6,Locking,摘要:在.net中锁定随机访问文件中的记录时,我们无法访问文件中锁定记录之前的记录 为了演示这个问题,我编写了两个简单的程序,一个打开并锁定一条记录,另一个尝试通读 结果是,当在第一个程序中锁定10条记录中的9条时,我们可以读取记录1和2,但不能读取更多!我们的期望(这是我们使用VB6的经验)是,您应该能够读取除锁定的记录之外的所有记录 有人见过这个问题吗?我在做什么奇怪的事吗?有工作吗 演示代码: 程序1创建/打开/锁定 Sub Main() Dim FileName As Stri

摘要:.net中锁定随机访问文件中的记录时,我们无法访问文件中锁定记录之前的记录

为了演示这个问题,我编写了两个简单的程序,一个打开并锁定一条记录,另一个尝试通读

结果是,当在第一个程序中锁定10条记录中的9条时,我们可以读取记录1和2,但不能读取更多!我们的期望(这是我们使用VB6的经验)是,您应该能够读取除锁定的记录之外的所有记录

有人见过这个问题吗?我在做什么奇怪的事吗?有工作吗

演示代码:

程序1创建/打开/锁定

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进行了测试,我们也遇到了同样的问题(当锁定一条记录时,前面的几条记录无法被其他单独的进程访问),如果您愿意,我也可以发布演示代码来显示。至于“完全”编写,我将在下周回到办公室时对此进行调查,但由于上述两个独立的代码位是在不同的开发实例中运行的,我不确定情况是否如此。返回的错误是一个建议锁定的错误,而不是类似的文件结束错误。