我有一个带有(文本/二进制)格式的大文件。
文件格式:( 0
代表一个字节)
00000FileName0000000Hello
World
world1
...
0000000000000000000000
目前我正在使用FileStream
,我想阅读Hello。
我知道Hello在哪里开始,它以0x0D 0x0A结束。
如果单词不等于Hello,我还需要返回。
如何在回车之前阅读?
PEEK
中是否有类似FileStream
的函数,所以我可以移回读指针?
FileStream
是不是一个好的选择?
答案 0 :(得分:1)
您可以使用FileStream.Seek方法更改读/写位置。
答案 1 :(得分:0)
您可以使用BinaryReader
来阅读二进制内容;但是,它使用内部缓冲区,因此您不能再依赖底层Stream.Position
,因为它可以在后台读取比您想要的更多的字节。但是你可以重新实现它所需的方法:
private byte[] ReadBytes(Stream s, int count)
{
buffer = new byte[count];
if (count == 0)
{
return buffer;
}
// reading one byte
if (count == 1)
{
int value = s.ReadByte();
if (value == -1)
threw new IOException("Out of stream");
buffer[0] = (byte)value;
return buffer;
}
// reading multiple bytes
int offset = 0;
do
{
int readBytes = s.Read(buffer, offset, count - offset);
if (readBytes == 0)
threw new IOException("Out of stream");
offset += readBytes;
}
while (offset < count);
return buffer;
}
public int ReadInt32(Stream s)
{
byte[] buffer = ReadBytes(s, 4);
return BitConverter.ToInt32(buffer, 0);
}
// similarly, write ReadInt16/64, etc, whatever you need
假设您处于起始位置,您也可以写一个ReadString
:
private string ReadString(Stream s, char delimiter)
{
var result = new List<char>();
int c;
while ((c = s.ReadByte()) != -1 && (char)c != delimiter)
{
result.Add((char)c);
}
return new string(result.ToArray());
}
用法:
FileStream fs = GetMyFile(); // todo
if (!fs.CanSeek)
throw new NotSupportedException("sorry");
long posCurrent = fs.Position; // save current position
int posHello = ReadInt32(fs); // read position of "hello"
fs.Seek(posHello, SeekOrigin.Begin); // seeking to hello
string hello = ReadString(fs, '\n'); // reading hello
fs.Seek(posCurrent, SeekOrigin.Begin); // seeking back