.net file random access recoard locking

独自空忆成欢 提交于 2020-01-05 01:35:11

问题


Summary: In .net When locking a record in a random access file we cannot access records ahead of the locked record in the file.

To demonstrate the issue I have written two simple programs one opens and locks a record and the other tries to read through.

The results are that when locking record number 9 out of the 10 in the first program we are able to read records 1 and 2 but no more! The expectation (And this is our experience with VB6) is that you should be able to read all the records apart from the one you have locked.

Has anyone seen this problem? Am I doing something strange? Any work around?

Demo Code:

Program 1 Create/Open/Lock

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

_

Program 2 Open and try and read

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

Edit 0.1: We have found that the deeper an individual record is locked within the file the more bytes/records are inaccessible before the locked one.


回答1:


Thanks all for your comments.

Posted the same question over on MSDN here and managed to get the answer.

So the conclusion is that with .net if you use FileGet or (e.g. System.IO.BinaryReader.ReadDouble()) the reader not only reads what you want but also buffers content meaning that a locked record ahead within the file is hit causing read failure.

But when using System.IO.FileStream.Read() and specifying exactly the number of bytes you want the buffer is not created allowing you to read all the records in a file except the locked one

Code example:

<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


来源:https://stackoverflow.com/questions/45106245/net-file-random-access-recoard-locking

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!