2017-07-14 74 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