我正在从二进制文件中读取字符串。每个字符串都以空值结尾。编码为 UTF-8。在 python 中,我只是读取一个字节,检查它是否为 0,将其附加到字节数组,然后继续读取字节,直到看到 0。然后我将字节数组转换为字符串并继续。所有字符串都被正确读取。
如何在 C# 中阅读此内容?我不认为我可以简单地将字节附加到数组中,因为数组是固定大小的。
我正在从二进制文件中读取字符串。每个字符串都以空值结尾。编码为 UTF-8。在 python 中,我只是读取一个字节,检查它是否为 0,将其附加到字节数组,然后继续读取字节,直到看到 0。然后我将字节数组转换为字符串并继续。所有字符串都被正确读取。
如何在 C# 中阅读此内容?我不认为我可以简单地将字节附加到数组中,因为数组是固定大小的。
以下应该可以为您提供所需的内容。所有文本都应该在 myText 列表中。
var data = File.ReadAllBytes("myfile.bin");
List<string> myText = new List<string>();
int lastOffset = 0;
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
myText.Add(System.Text.Encoding.UTF8.GetString(data, lastOffset, i - lastOffset));
lastOffset = i + 1;
}
}
我假设您使用的是 StreamReader 实例:
StringBuilder sb = new StringBuilder();
using(StreamReader rdr = OpenReader(...)) {
Int32 nc;
while((nc = rdr.Read()) != -1) {
Char c = (Char)nc;
if( c != '\0' ) sb.Append( c );
}
}
您可以使用List<byte>
:
List<byte> list = new List<byte>();
while(reading){ //or whatever your condition is
list.add(readByte);
}
string output = Encoding.UTF8.GetString(list.ToArray());
或者你可以使用StringBuilder
:
StringBuilder builder = new StringBuilder();
while(reading){
builder.Append(readByte);
}
string output = builder.ToString();
如果您的“二进制文件”仅包含以空字符结尾的 UTF8 字符串,那么对于 .NET,它不是“二进制文件”,而只是一个文本文件,因为空字符也是字符。因此,您可以只使用 StreamReader 来读取文本并将其拆分为空字符。(六年后,“你”可能会成为一些新读者,而不是 OP。)
单行(ish)解决方案是:
using (var rdr = new StreamReader(path))
return rdr.ReadToEnd().split(new char[] { '\0' });
但是,如果文件中的最后一个字符串被“正确”终止,那么这会给你一个尾随的空字符串。
一个更详细的解决方案可能对非常大的文件执行不同的操作,表示为 StreamReader 上的扩展方法,将是:
List<string> ReadAllNullTerminated(this System.IO.StreamReader rdr)
{
var stringsRead = new System.Collections.Generic.List<string>();
var bldr = new System.Text.StringBuilder();
int nc;
while ((nc = rdr.Read()) != -1)
{
Char c = (Char)nc;
if (c == '\0')
{
stringsRead.Add(bldr.ToString());
bldr.Length = 0;
}
else
bldr.Append(c);
}
// Optionally return any trailing unterminated string
if (bldr.Length != 0)
stringsRead.Add(bldr.ToString());
return stringsRead;
}
或者一次只阅读一个(如 ReadLine)
string ReadNullTerminated(this System.IO.StreamReader rdr)
{
var bldr = new System.Text.StringBuilder();
int nc;
while ((nc = rdr.Read()) > 0)
bldr.Append((char)nc);
return bldr.ToString();
}