StreamReader太贪婪 [英] StreamReader is too greedy

查看:44
本文介绍了StreamReader太贪婪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试处理文本文件的一部分,然后使用 UploadFromStream 将文本文件的其余部分写入云Blob.问题在于StreamReader似乎从底层流中获取了太多内容,因此后续的写入操作什么也不做.

I'm trying to process part of a text file, and write the remainder of the text file to a cloud blob using UploadFromStream. The problem is that the StreamReader appears to be grabbing too much content from the underlying stream, and so the subsequent write does nothing.

文本文件:

3
Col1,String
Col2,Integer
Col3,Boolean
abc,123,True
def,3456,False
ghijkl,532,True
mnop,1211,False

代码:

using (var stream = File.OpenRead("c:\\test\\testinput.txt"))
using (var reader = new StreamReader(stream))
{
    var numColumns = int.Parse(reader.ReadLine());
    while (numColumns-- > 0)
    {
        var colDescription = reader.ReadLine();
        // do stuff
    }

    // Write remaining contents to another file, for testing
    using (var destination = File.OpenWrite("c:\\test\\testoutput.txt"))
    {
        stream.CopyTo(destination);
        destination.Flush();
    }

    // Actual intended usage:
    // CloudBlockBlob blob = ...;
    // blob.UploadFromStream(stream);
}

调试时,我发现在第一次调用 reader.ReadLine()时, stream.Position 会跳到文件末尾,这是我所不希望的.我希望流只会根据读者阅读某些内容所需的位置而前进.

When debugging, I observe that stream.Position jumps to the end of the file on the first call to reader.ReadLine(), which I don't expect. I expected the stream to be advanced only as many positions as the reader needed to read some content.

我认为流读取器出于性能原因正在进行一些缓冲,但是似乎没有一种方法可以询问读取器真正"在底层流中的位置.(如果有的话,我可以在 CopyingTo 之前手动将流 Seek 移到该位置.)

I imagine that the stream reader is doing some buffering for performance reasons, but there doesn't seem to be a way to ask the reader where in the underlying stream it "really" is. (If there was, I could manually Seek the stream to that position before CopyingTo).

我知道我可以继续使用相同的阅读器记录行,然后将其顺序附加到我正在编写的文本文件中,但是我想知道是否有更干净的方法?

I know that I could keep taking lines using the same reader and sequentially append them to the text file I'm writing, but I'm wondering if there's a cleaner way?

我找到了一个StreamReader构造函数,该构造函数在处理底层流时将其保持打开状态,因此我尝试了此操作,希望读者可以在处理流时设置其位置:

I found a StreamReader constructor which leaves the underlying stream open when it is disposed, so I tried this, hoping that the reader would set the stream's position as it's being disposed:

using (var stream = File.OpenRead("c:\\test\\testinput.txt"))
{
    using (var reader = new StreamReader(stream, Encoding.UTF8, 
        detectEncodingFromByteOrderMarks: true, 
        bufferSize: 1 << 12, 
        leaveOpen: true))
    {
        var numColumns = int.Parse(reader.ReadLine());
        while (numColumns-- > 0)
        {
            var colDescription = reader.ReadLine();
            // do stuff
        }
    }

    // Write remaining contents to another file
    using (var destination = File.OpenWrite("c:\\test\\testoutput.txt"))
    {
        stream.CopyTo(destination);
        destination.Flush();
    }
}

但事实并非如此.如果没有让流处于直观状态/位置,为什么要暴露此构造函数?

But it doesn't. Why would this constructor be exposed if it doesn't leave the stream in an intuitive state/position?

推荐答案

当然,有一种更清洁的方法.使用 ReadToEnd 读取剩余数据,然后将其写入新文件.例如:

Sure, there's a cleaner way. Use ReadToEnd to read the remaining data, and then write it to a new file. For example:

using (var reader = new StreamReader("c:\\test\\testinput.txt"))
{
    var numColumns = int.Parse(reader.ReadLine());
    while (numColumns-- > 0)
    {
        var colDescription = reader.ReadLine();
        // do stuff
    }

    // write everything else to another file.
    File.WriteAllText("c:\\test\\testoutput.txt", reader.ReadToEnd());
}

评论后编辑

如果您想阅读文本并将其上传到流中,则可以将 File.WriteAllText 替换为读取剩余文本并将其写入 StreamWriter 的代码.>由 MemoryStream 支持,然后发送该 MemoryStream 的内容.像这样:

Edit after comment

If you want to read the text and upload it to a stream, you could replace the File.WriteAllText with code that reads the remaining text, writes it to a StreamWriter backed by a MemoryStream, and then sends the contents of that MemoryStream. Something like:

    using (var memStream = new MemoryStream())
    {
        using (var writer = new StreamWriter(memStream))
        {
            writer.Write(reader.ReadToEnd());
            writer.Flush();
            memStream.Position = 0;
            blob.UploadFromStream(memStream);
        }
    }

这篇关于StreamReader太贪婪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆