- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
首先我明白我可以用不同的方式解决这个问题。我想这个问题的存在只是因为以不正确的方式使用了不同的方法。但我想知道在我的示例中到底发生了什么。
我正在使用 StreamReader 读取文件。为了从中获取字节,我决定使用 BaseStream.Read:
int length = (int)reader.BaseStream.Length;
byte[] file = new byte[length];
while(!reader.EndOfStream)
{
int readBytes = reader.BaseStream.Read(file, 0,
(length-offset)>bufferSize?bufferSize:(length - offset));
for (int i = 0; i<readBytes; i++)
{
...
}
offset += readBytes;
}
在读取之前使用属性 StreamReader.EndOfStream 时,BaseStream.Read 拒绝获取最后 1024 个字节。后来查到资料,说EndOfStream试图读取1个字节,但实际上由于性能原因他读取了1024个字节。显然这 1kb 变得不可能达到。
编辑:如果我删除代码中的reader.EndOfStream 属性,reader.BaseStream.Read 将正常工作。这是问题的重点。
同样,我明白,这个代码示例绝对是低效的。我只是想了解流在那个例子中是如何工作的,这个问题是否仅仅因为错误的代码而存在(或者 StreamReader.BaseStream 有一些问题)?提前致谢。
最佳答案
不是 StreamReader.BaseStream
有一些问题,而是您的代码中的问题。当您直接使用包装在 StreamReader
中的 Stream
时。
来自 MSDN 关于 StreamReader.DiscardBufferedData :
You need to call this method only when the position of the internal buffer and the BaseStream do not match. These positions can become mismatched when you read data into the buffer and then seek a new position in the underlying stream.
这意味着,在你的情况下,当 Stream
已经到达结束位置时, StreamReader
internal buffer 的位置仍然保持之前的值您直接读取底层流,因此 reader.EndOfStream
仍然 = false
。这就是为什么您无法完成循环的原因。
编辑:
我觉得你漏掉了什么,我给你这段代码来证明文件成功到达结尾。运行它,您会看到您的应用重复说:我在文件末尾!
static void Main()
{
using (StreamReader reader = new StreamReader(@"yourFile"))
{
int offset = 0;
int bufferSize = 102400;
int length = (int)reader.BaseStream.Length;
byte[] file = new byte[length];
while (!reader.EndOfStream)
{
// Add this line:
Console.WriteLine(reader.BaseStream.Position);
Console.ReadLine();
int readBytes = reader.BaseStream.Read(file, 0,
(length - offset) > bufferSize ? bufferSize : (length - offset));
string str = Encoding.UTF8.GetString(file, 0, readBytes);
offset += readBytes;
if (reader.BaseStream.Position == length)
{
Console.WriteLine("I'm at the end of the file! Current Tickcount: " + Environment.TickCount);
Thread.Sleep(100);
}
}
}
}
编辑2
But still , offset and length should be equal, im my case length - offset = 1024 (in case of files that bigger than 1kb). Maybe I'm doing something wrong, but if I use files with size less than 1kb, readBytes always equals 0.
因为您第一次调用 while (!reader.EndOfStream)
,读取器必须读取文件(本例为 1024 字节 - 读取字节到内部缓冲区)以确定文件是否结束或不是(见我在上面添加的两行代码),在它读取文件后寻找 1024 字节,这就是为什么 length - offset = 1024
,如果你的文件很小超过 1kb 然后在第一次调用时,它已经找到文件末尾。这是您丢失数据的地方。
第二次调用它,它不寻找,因为你没有向读者发送任何读取请求,所以它认为不变,那么它不需要再次读取文件来检查是否在文件末尾,这就是为什么第二次通话不会丢失数据。
关于c# - 使用 EndOfStream 属性后的 StreamReader.BaseStream 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668357/
在MSE例子中,播放前调用endOfstream mediaSource.endOfStream(); video.play() https://developer.mozilla.org/en-US
我正在尝试使用代码(粘贴在下面)读取文本文件,但文件的最后一行没有被读取。我的逻辑正确吗? using (StreamReader reader = new StreamReader(
我编写了一个转换过滤器,它不会将前四帧的样本传递给渲染器,因为我在队列中提取和存储数据。因为对转换方法的调用等于帧数,所以我的最后 3 帧数据没有被调用并且数据丢失。如何解决 EndOfStream
BinaryReader 没有 EndOfStream 属性。使用以下代码检查是否已到达流结尾是否安全? reader.BaseStream.Length>reader.BaseStream.Posi
我正在我的 C# 应用程序中启动一个进程,该进程运行一个控制台应用程序。我已经重定向了标准输入和输出,并且能够通过 StandardOutput.ReadLine() 读取几行。我确信我已正确配置 P
所以我正在做一个项目,我正在读取配置文件。配置文件只是一个字符串列表,如“D 1 1”、“C 2 2”等。现在我还没有用 C# 进行过读/写,所以我在网上查找它希望找到某种形式的演绎C/C++ .eo
我正在编写一个大型应用程序,其中涉及来自进程或文件流的一些流。下面有两个示例,展示了检测流结束的不同方法。我很好奇有什么区别以及哪一个最好使用?效率或性能有什么区别吗?另外,在 .NET 引用指南中,
我正在使用一个使用 web 服务来推送一些事件的客户端 - web 服务的设计是这样的,即在客户端发布订阅命令时,它会发回一些感兴趣的事件并继续这样做只要客户端保持连接。 当 POST 命令时,服务会
正如标题所说,我发现了一个问题。先说小故事:我们的 file.txt 看起来像这样: aaaabb ccccddd eeeefffffff 有很多方法可以逐行阅读这段文字,其中一种是: StreamR
首先我明白我可以用不同的方式解决这个问题。我想这个问题的存在只是因为以不正确的方式使用了不同的方法。但我想知道在我的示例中到底发生了什么。 我正在使用 StreamReader 读取文件。为了从中获取
---简短版本:当我每次进入 while (!checkReader.EndOfStream) 时,它都会显示 EndOfStream = true。 ---更多细节:用户将使用 Ajax Async
我想在解析 XML 文档之前检测它的编码。所以我在堆栈上找到了overflow这个脚本。 public static XElement GetXMLFromStream(Stream uploadSt
我有一个 webrequest 可以创建与服务器的持久(保持事件)连接,例如: webRequest.ContentType = "application/x-www-form-urlencoded"
我写了这个小程序,它从 Random.txt 中每隔 5 个字符读取一次在 random.txt 中,我有一行文本:ABCDEFGHIJKLMNOPRST。我得到了预期的结果: A的位置为0 F的位置
我写了一个简单的测试项目,打开9123端口一段时间后退出: import java.io.IOException; import java.net.InetSocketAddress; import
我是一名优秀的程序员,十分优秀!