读取以null结尾的字符串

我正在从二进制文件中读取字符串。 每个字符串都以空值终止。 编码是UTF-8。 在python中,我只是读取一个字节,检查它是否为0,将其附加到字节数组,并继续读取字节,直到我看到0.然后我将字节数组转换为字符串并继续。 所有字符串都被正确读取。

我怎样才能在C#中读到这个? 我不认为我只是简单地将字节附加到数组,因为数组是固定大小的。

您可以使用List

 List list = new List(); 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(); 

以下应该可以满足您的需求。 所有文本都应该在myText列表中。

 var data = File.ReadAllBytes("myfile.bin"); List myText = new List(); 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 ); } } 

如果您的“二进制文件”仅包含空终止的UTF8字符串,那么对于.NET,它不是“二进制文件”而只是文本文件,因为空字符也是字符。 因此,您可以使用StreamReader读取文本并将其拆分为空字符。 (六年后,“你”可能是一些新的读者,而不是OP。)

一行(ish)解决方案是:

 using (var rdr = new StreamReader(path)) return rdr.ReadToEnd().split(new char[] { '\0' }); 

但是如果文件中的最后一个字符串“正确”终止,那将为您提供一个尾随空字符串。

对于非常大的文件可能执行不同的更详细的解决方案(在StreamReader上表示为扩展方法)将是:

 List ReadAllNullTerminated(this System.IO.StreamReader rdr) { var stringsRead = new System.Collections.Generic.List(); 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(); }