2013-04-06 84 views
2

嗨我试图扭转一个文件的字节,而无需将整个文件加载到内存中。到目前为止,我只设法读取文件的字节从开始到开始,但我我不知道如果我这样做corectly.This是我到目前为止有:颠倒文件中的字节顺序

 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

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

一个例子:

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

} 

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

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

+0

你能告诉我一个关于如何实现这个目标的例子吗? – aleczandru 2013-04-06 13:57:50

+0

@lasseespeholt,是的,这只是一个简单的例子 - 它可能是一个文件流,一个网络流或任何其他。 – driis 2013-04-07 08:28:16

3

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

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

这样的表现应该是快,但测试你的机器上是肯定的。

+0

该语言是C#。除此之外,很好的答案。 – driis 2013-04-06 14:20:50

+0

@driis哈哈:D我认为这是Java出于某种原因,所以我为此安装了IntelliJ;)C#即将推出。 – 2013-04-06 14:21:39

+1

@driis现在是C#。 – 2013-04-06 14:29:28