读取可能包含非ASCII字符的流

3

我有一个应用程序,从流中读取字符串数据。这些字符串通常是英文的,但有时会遇到像“Jalapeño”这样的字符串,其中的“ñ”会变成“?”。在我的实现中,我更喜欢将流内容读入字节数组,但如果将内容读入字符串也可以接受。你有什么办法可以让它正常工作吗?

当前代码如下:

byte[] data = new byte[len];  // len is known a priori
byte[] temp = new byte[2];
StreamReader sr = new StreamReader(input_stream);
int position = 0;
while (!sr.EndOfStream)
{
  int c = sr.Read();
  temp = System.BitConverter.GetBytes(c);
  data[position] = temp[0];
  position++;
}
input_stream.Close();
sr.Close();

int c 实际上保存的是一个字符或者 -1 表示文件结束(EOF),对于非 ASCII 值,看起来你正在丢弃一半的值 并且 从根本上改变编码方式... - undefined
2个回答

4
您可以将编码传递给StreamReader,例如:

编码

StreamReader sr = new StreamReader(input_stream, Encoding.UTF8);

然而,根据文档,默认情况下使用的是UTF8编码。

更新

以下内容读取“Jalapeño”正常:

byte[] bytes;
using (var stream = new FileStream("input.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    var index = 0;
    var count = (int) stream.Length;
    bytes = new byte[count];
    while (count > 0)
    {
        int n = stream.Read(bytes, index, count);
        if (n == 0)
            throw new EndOfStreamException();

        index += n;
        count -= n;
    }
}

// test
string s = Encoding.UTF8.GetString(bytes);
Console.WriteLine(s);

正如这样:
byte[] bytes;
using (var stream = new FileStream("input.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    var reader = new StreamReader(stream);
    string text = reader.ReadToEnd();
    bytes = Encoding.UTF8.GetBytes(text);
}

// test
string s = Encoding.UTF8.GetString(bytes);
Console.WriteLine(s);

据我所知,“ñ”字符在以UTF编码存储文本时表示为0xc391。当您只读取一个字节时,会丢失数据。建议将整个流读取为字节数组(第一个示例),然后进行编码。或者使用StreamReader来完成工作。

谢谢 - 但是即使指定了Encoding.UTF8,'ñ'字符仍然显示为'?'。 - undefined
1
请注意,Console.WriteLine 可能会为有效的 UNICODE 字符(如中文或日文)写入 "?"。 - undefined
谢谢Werner,上述的第二个例子"as does this"完美地运行了! - undefined

1

由于您正在尝试将内容填充到字节数组中,因此不要使用读取器 - 它对您没有帮助。只需使用流:

byte[] data = new byte[len];
int read, offset = 0;
while(len > 0 &&
    (read = input_stream.Read(data, offset, len)) > 0)
{
    len -= read;
    offset += read;
}
if(len != 0) throw new EndOfStreamException();

非常感谢,Marc。这对我很有帮助。我在复制字符串'Jalapeño'时遇到了一个后续问题。当我使用string s = System.Text.Encoding.UTF8.GetString(data)string s = System.Text.Encoding.Unicode.GetString(data)时,两者都不起作用。我得到了一个堆栈溢出异常(多么恰当!)。你能否推荐一种方法,在保留原始字符的同时从流中获取字符串? - undefined
@haxor,它是用哪种编码存储的? - undefined
这是我必须应对的挑战之一 - 我只能假设ASCII或UTF8。 - undefined
在“ISO 8859-1”编码中,'ñ'是字符0xf1。在“ISO-8859-7”中,0xf1表示'ρ'。 - undefined
所以回答这些问题,我们必须考虑编码页和UNICODE的变体,因为它涉及到拉丁字符(也称为'ñ')。 - undefined
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接