簡體   English   中英

讀取以null結尾的字符串

[英]Reading a null-terminated string

我正在從二進制文件中讀取字符串。 每個字符串都以空值終止。 編碼是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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM