我需要从流中读取第一行以确定文件的编码,然后使用该编码重新创建流
以下代码无效:
var r = response.GetResponseStream();
var sr = new StreamReader(r);
string firstLine = sr.ReadLine();
string encoding = GetEncodingFromFirstLine(firstLine);
string text = new StreamReader(r, Encoding.GetEncoding(encoding)).ReadToEnd();
文本变量不包含整个文本。由于某种原因,跳过第一行和几行后。
我尝试了一切:关闭StreamReader,重置它,调用一个单独的GetResponseStream ......但没有任何效果。
我无法再次获取响应流,因为我从互联网上获取此文件,再次重新加载它将是糟糕的性能。
更新
以下是GetEncodingFromFirstLine()的样子:
public static string GetEncodingFromFirstLine(string line)
{
int encodingIndex = line.IndexOf("encoding=");
if (encodingIndex == -1)
{
return "utf-8";
}
return line.Substring(encodingIndex + "encoding=".Length).Replace("\"", "").Replace("'", "").Replace("?", "").Replace(">", "");
}
...
// true
Assert.AreEqual("windows-1251", GetEncodingFromFirstLine(@"<?xml version=""1.0"" encoding=""windows-1251""?>"));
**更新2 **
我正在使用XML文件,文本变量被解析为XML:
var feedItems = XElement.Parse(text);
答案 0 :(得分:6)
嗯,你要求它检测编码......这需要它来读取数据。这是从底层流中读取它,然后您在同一个流周围创建另一个StreamReader
。
我建议你:
MemoryStream
)StreamReader
已经假设UTF-8 )< / LI>
MemoryStream
,并围绕StreamReader
目前还不清楚你的GetEncodingFromFirstLine
方法做了什么......或者这个文件究竟是什么。更多信息可以帮助您更轻松。
编辑:如果要加载一些XML,请不要重新发明轮子。只需将流提供给现有的XML解析类之一,它将为您执行适当的检测。
答案 1 :(得分:2)
您需要将流中的当前位置更改为开头。
r.Position = 0;
string text = new StreamReader(r, Encoding.GetEncoding(encoding)).ReadToEnd();
答案 2 :(得分:1)
我在这里找到了我的问题的答案:
How can I read an Http response stream twice in C#?
Stream responseStream = CopyAndClose(resp.GetResponseStream());
// Do something with the stream
responseStream.Position = 0;
// Do something with the stream again
private static Stream CopyAndClose(Stream inputStream)
{
const int readSize = 256;
byte[] buffer = new byte[readSize];
MemoryStream ms = new MemoryStream();
int count = inputStream.Read(buffer, 0, readSize);
while (count > 0)
{
ms.Write(buffer, 0, count);
count = inputStream.Read(buffer, 0, readSize);
}
ms.Position = 0;
inputStream.Close();
return ms;
}