2

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

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

        }

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

4

2 回答 2

4

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

一个例子:

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

} 

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

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

于 2013-04-06T13:56:38.983 回答
4

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

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++;
    }
}

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

于 2013-04-06T14:19:17.237 回答