.net:有没有一种方法可以从底部向上读取txt文件?

5

可能是重复问题:
如何在C#中使用迭代器反向读取文本文件

我想知道是否有一种方法可以从底部向上读取文本文件而没有任何性能损失,类似于readLine,movenext的方法,但是反过来,这种事情在.net中是否可能?

更有趣的是,该文本文件大约有100,000行,因此我不能通过readall,reverse等方式欺骗……

更多细节:我有一个包含前缀为int ID的传入字符串值的集合,可以进行排序。不幸的是,我以错误的顺序获得了这些ID。主要问题是字符串值的数量庞大,解决方案中没有RDBMS。因此,我真的需要一种存储字符串值的方法,然后在处理期间反转存储顺序。考虑到文本文件,因为我目前没有更好的解决方案。

提前感谢。


3
你是不是指从下往上? - Dave Archer
1
是的,从上到下是一种标准的方式... - Dan Tao
5
虽然我很希望能够因为我所做的工作而获得更多声誉,但事实上这是个重复的问题:https://dev59.com/Q3RB5IYBdhLWcg3w9b59 - Jon Skeet
谢谢Jon,我看到了你的回答,你觉得我添加行然后使用ODBC文本驱动程序以相反的顺序获取结果是否值得一试? - JL.
@JL:使用ODBC文本驱动程序可能比仅在内存中读取所有行并将其反转更昂贵。每行有多长? 80个字符的100,000行仍然只有约16MB... - Jon Skeet
显示剩余2条评论
6个回答

1

为什么不使用StreamReader类的ReadToEnd()方法,然后向后处理呢? 虽然这不太美观,但它确实有效。我使用了一个字节数组来创建一个MemoryStream实例,并将其用于StreamReader实例。通过指针操作,数据以反向方式读取。

unsafe
{
    byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello World! Foo wuz ere and so wuz bar");
    using (MemoryStream mStream = new MemoryStream(b))
    {
        string readStr;
        using (StreamReader sr = new StreamReader(mStream))
        {
            readStr = sr.ReadToEnd();
        }
        Console.WriteLine(readStr);
        fixed (char* beg = readStr)
        {
            char* p = beg + readStr.Length;
            while (p-- != beg)
            {
                Console.Write(*p);
            }
        }
    }
}

糟糕!我在测试代码时刚发布了这个帖子,结果就被关闭了...唉 - t0mm13b

0

如果你愿意深入研究,你可以使用二进制读取器并自己进行阅读...

你需要弄清楚如何反向确定行尾,并找出如何确保你拥有正确的编码。

我认为这相当令人望而生畏。


你说得对,这很痛苦。不过还是挺有趣的 :) - Jon Skeet

0

一般性的回答。如果有某种形式的peek()方法,你可能可以将文件指针设置为filesize(或filesize - 1?),然后递减指针直到达到0。.NET中可能有一些抽象出来的类。当然,您必须定义某种缓冲区大小(基本上定义您正在读取的文件“块”的大小)。在这种情况下,上面的filesize - 1可能会变成filesize - bufferSize,您还将通过bufferSize增加文件指针。


0

我认为你可以做到这一点,可以使用PInvoke通过WINAPI来达成目的。你需要创建一个内存映射文件,但仅映射文件的结尾并向上移动。


0

所以您得到的值是错误的顺序,但希望以正确的顺序检索它们。也许是

Stack<T> 

这对你来说可行。

http://msdn.microsoft.com/en-us/library/3278tedw.aspx

表示一种可变大小的后进先出(LIFO)集合,其中包含相同任意类型的实例。


谢谢,这是很棒的知识,但不幸的是我最初使用一系列批处理调用来填充我的列表,否则这将非常有效。 - JL.

-1

StreamReader类的ReadBlock方法允许您从特定位置读取。关于性能不确定,您可能希望将其读入数组,然后反转它。


很抱歉,我已经超出了由于内存限制和高容量而将所有内容加载到集合中的点。 - JL.
ReadBlock 允许您从数组中的特定位置读取,它是写入的数组。它不允许您指定读取器内要读取的索引。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接