VB.NET同时读写文件

时间:2014-06-29 13:22:52

标签: vb.net filestream streamwriter

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

我有这段代码,但我不能同时读取和写入同一个文件......

' 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))

1 个答案:

答案 0 :(得分:0)

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

反对这一点:

  • 如果出现问题(例如电源故障),你将会有一个很大的混乱来清理
  • 如果您使用的是硬盘驱动器,那对所有人来说都会有点残忍 如果您没有合适的BUFFERSIZE
  • ,请寻求

话虽如此,以下只需要几秒钟就可以在SSD上1GB文件的开头附近切一小部分,或者在硬盘上不到10秒。

N.B。我偶然检查一下它是否正常工作,但可能在某处出现了一个错误。

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:\temp\a.dat"
        CreateTestData(filename)
        CutMiddleOutOfFile(filename, 2048, 1024)
        Console.WriteLine("Done.")
        Console.ReadLine()

    End Sub

End Module