gpt4 book ai didi

c# - 在流读取器对象的Position位置大于buffersize之后,C#streamreader的Read(char [] buffer,int index,int count)方法无法从文件读取

转载 作者:太空狗 更新时间:2023-10-30 01:31:34 24 4
gpt4 key购买 nike

更新:
我可以确定下面提到的行为是由我造成的
做一些我之前没有指定的事情,那就是我正在手动使用reader charpos属性,因此问题可以被重命名为:“如何搞砸你的工作精细读取(buffer,int,int)method“,答案是简单地手动设置读卡器(sr1)在流(fsr)缓冲区大小之外的位置(不要与读操作缓冲区混淆):
循环之前(在原始问题的代码中)

 System.Reflection.FieldInfo charPos_private = typeof(StreamReader).GetField("charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);

在循环中(在原始问题的代码中)
charPos_private.SetValue(SR1, string_index);

文件读取器实际读取1024个字符,然后当文件流读取下一个1024个字符时,它将变为0。我试图手动设置位置(因为我弄乱了一些模式),但我没有注意到它永远不能到1025。
然后,你就这样搞砸了简单的事情。
非常感谢所有的评论!非常感谢!我将把答案设置为一个包含如何正确操作的示例的答案,如果不是我没有提到的那几行代码,我发布的代码也可以正常工作。
原题
第一次来这里,
我在自学。我试图使用streamreader从一个大的utf-8linux lf(结束于(xml)char-by-char(或block-by-block)中读取数据,并对其执行一些操作,然后将其逐个char(或block-by-block)写入新文件。我有一个streamreader和streamwriter。
我将用文字解释并在最后添加一些代码:
我发现streamreader read()和read(char[]buffer,int index,int count)方法可以在大文件上执行不同的操作。我知道这两种方法只不过是调用同一个方法的两种不同方式(我也尝试过readblock),但情况是:read()方法自动用buffer(数组)动态填充streamreader对象,也就是当streamreader对象位置达到默认的buffersize参数(通常是1024或4096)时,方法自动开始缓冲下一个1024或4096或任何缓冲大小。
但是read(char[]buffer,int index,int count)不会自动执行此操作,因此当streamreader对象位置达到buffersize+1时会引发异常。即位于1025位置或4097位置(char)(system.buffer.internalblockcopy上的system.indexAutoFrangeException(array src,int32 srcOffsetBytes,array dst,int32 dstOffsetBytes,int32 byteCount))或如果我尝试peek()查看下一步(system.io.streamreader.peek()上的system.indexAutoFrangeException)。我的测试文件是300MB。
*问题是:如何让read(char[]buffer,int index,int count)自动拒绝bytebuffer(streamreader:non public members bytebuffer),以便有效地读取大于缓冲区大小的文件?或者换句话说:我如何用read读取一个大文件(buffer_search,0,x_number_of_chars)?*
我的意思是我不知道是否需要通过系统反射手动修改bytebuffer,以及如何修改。它应该是自动的;手动重新缓冲对于一件简单的事情来说太多工作了。
在代码中:(我在这里解释一些代码)
做一些类似的事情:
char current_char;
using (System.IO.FileStream FSw = new FileStream(sourcePath, FileMode.Create))
{
using (System.IO.StreamWriter SW1 = new StreamWriter(FSw, System.Text.Encoding.UTF8))
{
using (FileStream FSr = new FileStream(destinationPath, FileMode.Open))
{
using (StreamReader ofile_temp_chars = new StreamReader(fsr, System.Text.Encoding.UTF8))
{
while ((current_char = (char)SR1.Read()) != '\uffff')
{
SW1.Write(current_char);
}
}
}
}
}

代码是成功的,没有问题。大文件被读入写入一个新文件。
但是,当我试图指定要读取的字符数时(实际上我必须读取用户定义的字符数,我只是在这里显示一些只读取一个字符的代码来简化),我需要使用read(char[]buffer,int index,int count),如下所示:
char[] buffer_search = new char[1]
using (System.IO.FileStream FSw = new FileStream(fePath, FileMode.Create))
{
using (System.IO.StreamWriter SW1 = new StreamWriter(FSw, System.Text.Encoding.UTF8))
{
using (FileStream FSr = new FileStream(fPath, FileMode.Open))
{
using (StreamReader ofile_temp_chars = new StreamReader(fsr, System.Text.Encoding.UTF8))
{
while (SR1.Peek() != -1)
{
SR1.Read(buffer_search, 0, 1);
SW1.Write(buffer_search[0]);
}
}
}
}
}

当streamreader对象位置达到并通过bufferSize(即1025、4097)等时,该代码将以异常结束(system.indexAutoFrangeException on system.io.streamReader.peek())。很明显,它是从缓冲区而不是文件本身的内容中窥视,并且不会自动拒绝,这会导致窥视bytebuffer char[]之外的内容。
如果我这样做:
char[] buffer_search = new char[1]
using (System.IO.FileStream FSw = new FileStream(fePath, FileMode.Create))
{
using (System.IO.StreamWriter SW1 = new StreamWriter(FSw, System.Text.Encoding.UTF8))
{
using (FileStream FSr = new FileStream(fPath, FileMode.Open))
{
using (StreamReader SR1 = new StreamReader(fsr, System.Text.Encoding.UTF8))
{
while (!end_of_file)
{
try { SR1.Read(buffer_search, 0, 1); }
catch { end_of_file = true; }
SW1.Write(buffer_search[0]);
}
}
}
}
}

然后我将得到一个只包含1024个字符的文件,或者缓冲区大小是多少。将引发的异常(捕获)为:
System.Buffer.InternalBlockCopy上的System.IndexAutoFrangeException(数组src,Int32 srcOffsetBytes,数组dst,Int32 dstOffsetBytes,Int32字节计数)
在system.io.streamreader.read上(char[]buffer,int32 index,int32 count)
因此,在这两种情况下,结果都是相同的,缓冲区不会从文件中获取新数据,这是由read()和readline()方法自动处理的。
简单的解决方案,如增加缓冲区大小将无法工作,因为我的文件是在数百MB,我正在努力提高内存效率…(或者更简单,比如使用read(),因为我需要使用read(buffer,0,x_number_of_chars)。这应该是一件简单的事情,而且花费的时间比预期的要长。
谢谢你的帮助,

最佳答案

你的要求真的不清楚。但是,如果要从一个流读取器中读取任意数量的字符并将其写入一个写入器,则可以:

int bytesRead;
do
{
bytesRead = SR1.Read(buffer_search, 0, buffer_search.Length);
if (bytesRead > 0)
{
// TODO: process buffer_search in some way.
SW1.Write(buffer_search, 0, bytesRead);
}
} while (bytesRead > 0);

它将在需要时将新字符读入内部流编写器缓冲区。

关于c# - 在流读取器对象的Position位置大于buffersize之后,C#streamreader的Read(char [] buffer,int index,int count)方法无法从文件读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40769137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com