VB.NET同时读取和写入文件



我想删除位于文件中间的数据,因为文件很大,我想避免重写整个文件。要移动我正在尝试的数据:从数据结束(字节位置)到文件结束->到数据开始(字节位置),然后截断文件到文件大小-数据大小。

我有这个代码,但我不能让它在同一时间读取和写入同一个文件…

' Read from end of data in file to byte position of start of data in file
Using inFile As New System.IO.FileStream(NAME, IO.FileMode.Open, IO.FileAccess.Read)
    Using outFile As New System.IO.FileStream(NAME, IO.FileMode.Open, IO.FileAccess.Write)
        inFile.Seek((START_POS + DATA_SIZE), IO.SeekOrigin.Begin)
        outFile.Seek(START_POS, IO.SeekOrigin.Begin)
        Do
            If FILESIZE - CURRENT_TOTAL_READ < BUFFER_SIZE Then
                ReDim BUFFER((FILESIZE - 1) - CURRENT_TOTAL_READ)
            End If
            BYTES_READ = inFile.Read(BUFFER, 0, BUFFER.Length)
            If BYTES_READ > 0 Then
                outFile.Write(BUFFER, 0, BYTES_READ)
                CURRENT_TOTAL_READ += BYTES_READ
            End If
        Loop While BYTES_READ > 0 AndAlso CURRENT_TOTAL_READ < (DATA_SIZE- 1)
    End Using
End Using
TOTAL_PROCESSED_DATA += CURRENT_TOTAL_READ
' truncate file to file size - data size
TRUNCATE(NAME, (FILESIZE - DATA_SIZE))

您可以使用一个文件流,并在每次读写之前设置其位置。

反对:

  • 如果它出了问题(例如电源故障),你将有一个大烂摊子要清理
  • 如果你使用的是硬盘驱动器,那就有点残忍了如果你没有合适的BUFFERSIZE

话虽如此,下面的操作只需要几秒钟就可以在SSD上切掉1GB文件开头的一小部分,而在HDD上则不到十秒钟。

注意:我做了一个偶然的检查,它的工作正常,但有可能是一个off-by- 1错误在那里的某个地方。

Imports System.IO
Module Module1
    Sub CreateTestData(filename As String)
        If File.Exists(filename) Then
            File.Delete(filename)
        End If
        ' put AAAA....BBBB... etc at the start of the file for easy inspection
        Using sw As New StreamWriter(filename)
            For c = Asc("A") To Asc("D")
                Dim s = New String(Chr(c), 1024)
                sw.Write(s)
            Next
        End Using
        ' Make the file 1GB in size.
        Using fs As New FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
            fs.SetLength(1024 * 1024 * 1024)
        End Using
    End Sub
    Sub CutMiddleOutOfFile(filename As String, cutPos As Int64, cutLength As Int64)
        If cutPos < 0 OrElse cutLength < 0 Then
            Throw New ArgumentException("Cut parameters must be positive.")
        End If
        'TODO: More argument checking regarding cutPos, cutLength, and the length of the file.
        ' Use a fairly large buffer
        Const BUFFERSIZE As Integer = 1024 * 1024
        ' Let FileStream decide its own internal buffer size.
        Using fs As New FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
            Dim buffer(BUFFERSIZE) As Byte
            Dim bytesRead As Integer = Integer.MaxValue
            Dim currReadPos As Int64 = cutPos + cutLength
            Dim currWritePos As Int64 = cutPos
            While bytesRead > 0
                fs.Position = currReadPos
                bytesRead = fs.Read(buffer, 0, BUFFERSIZE)
                If bytesRead > 0 Then
                    fs.Position = currWritePos
                    fs.Write(buffer, 0, bytesRead)
                End If
                currReadPos += bytesRead
                currWritePos += bytesRead
            End While
            fs.SetLength(currWritePos)
        End Using
    End Sub
    Sub Main()
        Dim filename = "D:tempa.dat"
        CreateTestData(filename)
        CutMiddleOutOfFile(filename, 2048, 1024)
        Console.WriteLine("Done.")
        Console.ReadLine()
    End Sub
End Module

相关内容

  • 没有找到相关文章

最新更新