c#:如何从流中读取一行,然后从头开始读取

本文关键字:读取 一行 从头开始 然后 | 更新日期: 2023-09-27 18:05:12

我需要从流中读取第一行来确定文件的编码,然后用该编码重新创建流

下面的代码不能正常工作:

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();

text变量不包含整个文本。由于某些原因,第一行和其后的几行被跳过。

我尝试了一切:关闭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);

c#:如何从流中读取一行,然后从头开始读取

你要求它检测编码…这需要它读取数据。这是从底层流中读取它,然后在同一流周围创建另一个StreamReader

我建议你:

  • 获取响应流
  • 将所有数据检索到字节数组(或MemoryStream)
  • 检测编码(应该在字节上执行,而不是文本-目前您已经通过创建StreamReader假设UTF-8)
  • 在字节数组周围创建MemoryStream,并在
  • 周围创建StreamReader

不清楚你的GetEncodingFromFirstLine方法做什么…或者这个文件到底是什么。更多的信息可能会更容易帮助你。

编辑:如果这是加载一些XML,不要重新发明轮子。只需将该流交给一个现有的xml解析类,它将为您执行适当的检测。

您需要将流中的当前位置更改到开始

r.Position = 0;
string text = new StreamReader(r, Encoding.GetEncoding(encoding)).ReadToEnd();

我在这里找到了我问题的答案:

如何在c#中读取Http响应流两次?

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;
}