2017-07-14 70 views
2

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

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

结果是,当在第一个程序中锁定第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:我们发现单个记录被锁定在文件中的越深,在被锁定的文件之前无法访问的字节/记录越多。

+0

urg ...开始使用System.IO。无论如何,文件并不总是“完全”写入,你需要关闭或刷新流。 –

+0

为什么选择vb6标签? vb6!= vb.net。 –

+0

可能是兼容库中的一个bug;有记录的行为是为了锁定锁定单个记录。 – Craig

回答

0

谢谢大家的意见。

在MSDN here上发布了同样的问题并设法得到答案。

所以得出的结论是,与.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