![](/img/trans.png)
[英]C#: FileStream.Read() doesn't read the file up to the end, but returns 0
[英]C# FileStream.Read doesn't read last block
我逐块读取二进制文件到十六进制。
当我使用 FileStream.Read 和 File.ReadAllBytes 时它是不同的
FileSteram.Read
int limit = 0; if (openFileDlg.FileName.Length > 0) { fileName = openFileDlg.FileName; FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); fsLen = (int)fs.Length; int count = 0; limit = 100; byte[] read_buff = new byte[limit]; StringBuilder sb = new StringBuilder(); while ( (count = fs.Read(read_buff, 0, limit)) > 0) { foreach (byte b in read_buff) { sb.Append(Convert.ToString(b, 16).PadLeft(2, '0')); } } rtxb_bin.AppendText(sb.ToString() + "\\n"); }
File.ReadAllBytes
if (openFileDlg.FileName.Length > 0) { fileName = openFileDlg.FileName; byte[] fileBytes = File.ReadAllBytes(fileName); StringBuilder sb2 = new StringBuilder(); foreach (byte b2 in fileBytes) { sb2.Append(Convert.ToString(b2, 16).PadLeft(2, '0')); } rtxb_allbin.AppendText(sb2.ToString()); }
案例1,结果是...
........04c0020f00452a00421346108129844f2138448500208020250405250043188510812e0
情况2是
.......04c0020f00452a00421346108129844f2138448500208020250405250043188510812e044f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047
FileStream.Read 在 '12e0' '44f212cc48120c24125404f2069c2c0008bff35f8f401efbd17047' 丢失后不读取
如何使用 FileStream.Read 读取所有字节?
为什么 FileStream.Read 不读取最后一个块?
在您看来,它很可能没有读取最后一个块。 假设您有长度为 102 的文件。循环的第一次迭代读取前 100 个字节,一切正常。 但是第二个(最后一个)会发生什么呢? 您将两个字节读入read_buff
,其长度为 100。现在该缓冲区包含最后一个块的 2 个字节和前一个(第一个)块的 98 个字节,因为Read
不会清除缓冲区。 然后你继续:
foreach (byte b in read_buff)
{
sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
}
结果, sb
有第一个块的 100 个字节,最后一个块的 2 个字节,然后是第一个块的 98 个字节。 如果你不仔细看,它可能看起来只是跳过了最后一个块,而实际上它复制了前一个块的一部分。
要修复,请使用count
(指示实际读入缓冲区的字节count
)仅与read_buff
有效部分一起使用:
for (int i = 0; i < count; i++) {
sb.Append(Convert.ToString(read_buff[i], 16).PadLeft(2, '0'));
}
您需要更新偏移量和计数。
辛塔西斯
public override int Read(
byte[] array,
int offset,
int count
)
例子
public static byte[] ReadFile(string filePath)
{
byte[] buffer;
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read
// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
sum += count; // sum is a buffer offset for next reading
}
finally
{
fileStream.Close();
}
return buffer;
}
public static void ReadAndProcessLargeFile(string theFilename, long whereToStartReading = 0)
{
FileInfo info = new FileInfo(theFilename);
long fileLength = info.Length;
long timesToRead = (fileLength / megabyte);
long ctr = 0;
long timesRead = 0;
FileStream fileStram = new FileStream(theFilename, FileMode.Open, FileAccess.Read);
using (fileStram)
{
byte[] buffer = new byte[megabyte];
fileStram.Seek(whereToStartReading, SeekOrigin.Begin);
int bytesRead = 0;
//bytesRead = fileStram.Read(buffer, 0, megabyte);
//ctr = ctr + 1;
while ((bytesRead = fileStram.Read(buffer, 0, megabyte)) > 0)
{
ProcessChunk(buffer, bytesRead);
buffer = new byte[megabyte]; // This solves last read prob
}
}
}
private static void ProcessChunk(byte[] buffer, int bytesRead)
{
// Do the processing here
string utfString = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.Write(utfString);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.