【问题标题】:Reversing the order of bytes in a file反转文件中字节的顺序
【发布时间】:2014-07-01 02:18:58
【问题描述】:

您好,我正在尝试在不将整个文件加载到内存的情况下反转文件的字节。到目前为止,我只设法从头到尾读取文件的字节,但我不确定我是否正在这样做corectly。这是我到目前为止所拥有的:

        FileStream fileStream = new FileStream("file.txt", FileMode.Open, FileAccess.ReadWrite);
        fileStream.Seek(1024, SeekOrigin.End);
        byte[] buffer = new byte[1024];
        int count;
        while (fileStream.Position != 0)
        {
            count = fileStream.Read(buffer, 0, 1024);

        }

现在如何反转文件的字节顺序并以相反的顺序保存?

【问题讨论】:

    标签: c#


    【解决方案1】:

    我认为你最好分块读取文件,从最后一个块开始,读取每个块并以相反的顺序写入这些字节。

    一个例子:

    MemoryStream output = new MemoryStream();
    FileStream fs = new FileStream("D:\\file.txt", FileMode.Open);
    long pos = fs.Length;
    fs.Seek(0, SeekOrigin.End);
    byte[] buffer = new byte[blockSize];
    int length = blockSize;
    while(pos > 0) {
    
        length = (int)(pos < blockSize ? pos : blockSize);
        pos -= length;
        fs.Seek(pos, SeekOrigin.Begin);
    
        int read = fs.Read(buffer,0, length);
        byte[] reversed = buffer.Take(read).Reverse().ToArray();
        output.Write(reversed,0, read);
    
    } 
    

    为了简单起见,假设 Stream 在请求时实际上正在读取 length 字节。 FileStream 这样做 - 但在其他 Stream 实现的情况下,它们可能不会(网络流等)。

    您也可以为此使用memory mapped file,正如另一个答案中所建议的那样。我不知道在 .NET 中使用内存映射文件的确切开销,所以如果这对您很重要,请尝试使用您需要处理的实际文件大小来衡量这两种方法。如果文件很大而缓冲区很小,则逐块方法涉及大量文件查找。另一方面,设置内存映射文件会有开销。

    【讨论】:

    • @lasseespeholt,是的,这只是一个简单的例子——它可以是文件流、网络流或其他任何东西。
    【解决方案2】:

    您可以像这样使用内存映射文件:

    using System.IO.MemoryMappedFiles;
    using System.IO;
    
    ...
    
    string filename = @"filename";
    
    long length = new FileInfo(filename).Length;
    
    using (var file = MemoryMappedFile.CreateFromFile(filename, FileMode.Open))
    using (var accessor = file.CreateViewAccessor()) {
        // Reverse
        long i = 0;
        long j = length - 1;
        byte tmp;
        while (j > i)
        {
            tmp = accessor.ReadByte(j);
            accessor.Write(j, accessor.ReadByte(i));
            accessor.Write(i, tmp);
            j--;
            i++;
        }
    }
    

    这样做的性能应该很快,但请在您的机器上测试以确保。

    【讨论】:

    • @driis 哈哈 :D 我认为它是 Java 出于某种原因,所以我为此安装了 IntelliJ ;) C# 即将推出。
    • 那我给答案+1 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    相关资源
    最近更新 更多