【问题标题】:Efficiently merge file chunks高效合并文件块
【发布时间】:2014-12-24 02:37:37
【问题描述】:

您好,我正在尝试将拆分文件重新合并在一起。我有这个代码工作,但它非常缓慢。有什么想法可以加快速度吗?每个文件块最多可以包含 5mb 个块,并且可以有 100 个或更多块可以重新组合在一起。我将块文件路径“mergeFileNameArray”的数组以及新合并文件的“文件名”传递给它。

非常感谢!

    Dim STo As System.IO.Stream = System.IO.File.Open _
                (filename, _
                 System.IO.FileMode.Create, _
                 System.IO.FileAccess.Write)
    Dim BW As New System.IO.BinaryWriter(STo)

    For Each F In mergeFileNameArray
        Dim STi As System.IO.Stream = System.IO.File.Open _
             (F, _
              System.IO.FileMode.Open, _
              System.IO.FileAccess.Read)
        Dim BR As New System.IO.BinaryReader(STi)
        Do Until (BR.BaseStream.Position = BR.BaseStream.Length)
            BW.Write(BR.ReadByte)
        Loop
        BR.Close()
    Next
    BW.Close()

【问题讨论】:

    标签: .net vb.net


    【解决方案1】:

    一次复制一个字节的文件效率并不高。相反,您可以使用缓冲区和FileStreams 复制文件块;这是最基本的:

    Option Infer On
    Imports System.IO
    
    Module Module1
    
        Sub ConcatenateFileParts(fileParts As String(), destFile As String)
            Using outStream As New FileStream(destFile, FileMode.Create, FileAccess.Write, FileShare.None)
                Dim bufferLength = 32768
                Dim buffer(bufferLength - 1) As Byte
                Dim bytesRead As Integer
                For Each inFile In fileParts
                    Using inStream As New FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read)
                        bytesRead = inStream.Read(buffer, 0, bufferLength)
                        While bytesRead > 0
                            outStream.Write(buffer, 0, bytesRead)
                            bytesRead = inStream.Read(buffer, 0, bufferLength)
                        End While
                    End Using
                Next
            End Using
    
        End Sub
    
        Sub Main()
            ' I put a couple of files in "C:\temp\subdir" for testing.
            Dim filesToMerge = Directory.GetFiles("C:\temp\subdir")
            Dim dest = "C:\temp\merged.txt"
            Try
                ConcatenateFileParts(filesToMerge, dest)
            Catch ex As Exception
                MsgBox("File merge failed because " & ex.Message)
            End Try
    
        End Sub
    
    End Module
    

    Using 构造确保文件流被正确关闭和处理。

    您可以通过报告进度来使其更加复杂,例如在复制每个文件部分后增加一个计数器。

    【讨论】:

    • 嗨,谢谢。我遇到了访问问题“在 mscorlib.dll 中发生了‘System.UnauthorizedAccessException’类型的第一次机会异常”有什么想法可以克服这个问题吗?
    • @WilliamContestabile 好的,注释掉“Try”、“Catch...”、“MsgBox(...”和“End Try”这几行,然后按 F5 调试程序。哪一行它现在抱怨吗?如果是与读取文件有关的行,那么运行程序的用户没有读取要连接的文件的权限,如果是与写入输出文件有关的行,那么类似,但用于写入该文件。
    • @WilliamContestabile 不客气 :) 它加快了很多吗?您可以尝试将 bufferLength 更改为 65536 或 16384 等值,以防有更多帮助。
    • 巨大的差异,快得多!是的,我玩过缓冲区。认为我将不得不花一些时间进行报告和日志记录,以找出最有效的设置。块大小和最终文件大小以及块数量因作业而异。它需要做一些工作才能对其进行微调,但这个法拉利代码比我的拉达代码好得多!
    猜你喜欢
    • 2012-05-20
    • 2019-04-20
    • 2017-03-26
    • 2020-03-08
    • 1970-01-01
    • 2016-07-02
    • 2019-09-17
    • 2018-09-21
    • 1970-01-01
    相关资源
    最近更新 更多