4

嗨,我正在尝试以相反的顺序一次读取一个文件。到目前为止,我只设法从头到尾读取文件并将其写入另一个文件。

我需要能够从头到尾读取文件并将其打印到另一个文件。

这是我到目前为止所拥有的:

        string fileName = Console.ReadLine();
        using (FileStream file = new FileStream(fileName ,FileMode.Open , FileAccess.Read))
        {

            //file.Seek(endOfFile, SeekOrigin.End);

            int bytes;
            using (FileStream newFile = new FileStream("newsFile.txt" , FileMode.Create , FileAccess.Write))
            {
                while ((bytes = file.ReadByte()) >= 0)
                {
                    Console.WriteLine(bytes.ToString());
                    newFile.WriteByte((byte)bytes);
                }
            }
        }

我知道我必须在 fileStream 上使用 Seek 方法,这会让我到达文件的末尾。我已经在代码的注释部分这样做了,但我现在不知道如何读取文件环形。

我怎样才能做到这一点?

4

4 回答 4

1
    string fileName = Console.ReadLine();
    using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        byte[] output = new byte[file.Length]; // reversed file 

        // read the file backwards using SeekOrigin.Current
        //
        long offset;
        file.Seek(0, SeekOrigin.End);        
        for (offset = 0; offset < fs.Length; offset++)
        {
           file.Seek(-1, SeekOrigin.Current);
           output[offset] = (byte)file.ReadByte();
           file.Seek(-1, SeekOrigin.Current);
        }

        // write entire reversed file array to new file
        //
        File.WriteAllBytes("newsFile.txt", output);
    }
于 2013-04-10T16:56:49.553 回答
1

您可以一次读取一个字节,或者您可以读取一个更大的缓冲区,将其反向写入输出文件,然后像这样继续,直到到达文件的开头。例如:

string inputFilename = "inputFile.txt";
string outputFilename = "outputFile.txt";
using (ofile = File.OpenWrite(outputFilename))
{
    using (ifile = File.OpenRead(inputFilename))
    {
        int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];
        long filePos = ifile.Length;
        do
        {
            long newPos = Math.Max(0, filePos - bufferSize);
            int bytesToRead = (int)(filePos - newPos);
            ifile.Seek(newPos, SeekOrigin.Set);
            int bytesRead = ifile.Read(buffer, 0, bytesToRead);
            // write the buffer to the output file, in reverse
            for (int i = bytesRead-1; i >= 0; --i)
            {
                ofile.WriteByte(buffer[i]);
            }
            filePos = newPos;
        } while (filePos > 0);
    }
}

一个明显的优化是在您读取缓冲区后反转缓冲区,然后将其以一整块的形式写入输出文件。

如果您知道该文件将适合内存,那真的很容易:

var buffer = File.ReadAllBytes(inputFilename);
// now, reverse the buffer
int i = 0;
int j = buffer.Length-1;
while (i < j)
{
    byte b = buffer[i];
    buffer[i] = buffer[j];
    buffer[j] = b;
    ++i;
    --j;
}
// and write it
File.WriteAllBytes(outputFilename, buffer);
于 2013-04-10T17:33:19.700 回答
0

如果文件很小(适合您的 RAM),那么这将起作用:

public static IEnumerable<byte> Reverse(string inputFilename)
{
    var bytes = File.ReadAllBytes(inputFilename);
    Array.Reverse(bytes);

    foreach (var b in bytes)
    {
        yield return b;
    }
}

用法:

foreach (var b in Reverse("smallfile.dat"))
{

}
于 2021-07-09T15:21:25.930 回答
0

如果文件很大(比您的 RAM 大),那么这将起作用:

using (var inputFile = File.OpenRead("bigfile.dat"))
using (var inputFileReversed = new ReverseStream(inputFile))
using (var binaryReader = new BinaryReader(inputFileReversed))
{
    while (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
    {
        var b = binaryReader.ReadByte();
    }
}

它使用ReverseStream可以在此处找到的类。

于 2021-07-09T15:25:31.313 回答