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

发布于 2024-11-28 12:51:24 字数 1148 浏览 5 评论 0原文

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

以下代码无法正常工作:

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

I need to read the first line from a stream to determine file's encoding, and then recreate the stream with that Encoding

The following code does not work correctly:

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

The text variable doesn't contain the whole text. For some reason the first line and several lines after it are skipped.

I tried everything: closing the StreamReader, resetting it, calling a separate GetResponseStream... but nothing worked.

I can't get the response stream again as I'm getting this file from the internet, and redownloading it again would be bad performance wise.

Update

Here's what GetEncodingFromFirstLine() looks like:

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""?>")); 

** Update 2 **

I'm working with XML files, and the text variable is parsed as XML:

var feedItems = XElement.Parse(text);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

残疾 2024-12-05 12:51:24

好吧,您要求它检测编码...这需要它读取数据。这是从底层流中读取它,然后您围绕同一流创建另一个 StreamReader

我建议您:

  • 获取响应流
  • 将所有数据检索到字节数组(或 MemoryStream)中
  • 检测编码(应该在字节上执行,而不是文本 - 目前您通过创建 StreamReader已经采用 UTF-8
  • 围绕字节数组创建一个 MemoryStream 和一个 StreamReader > 围绕那个

目前尚不清楚您的 GetEncodingFromFirstLine 方法的作用......或者该文件到底是什么。更多信息可能会更容易为您提供帮助。

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

Well you're asking it to detect the encoding... and that requires it to read data. That's reading it from the underlying stream, and you're then creating another StreamReader around the same stream.

I suggest you:

  • Get the response stream
  • Retrieve all the data into a byte array (or MemoryStream)
  • Detect the encoding (which should be performed on bytes, not text - currently you're already assuming UTF-8 by creating a StreamReader)
  • Create a MemoryStream around the byte array, and a StreamReader around that

It's not clear what your GetEncodingFromFirstLine method does... or what this file really is. More information may make it easier to help you.

EDIT: If this is to load some XML, don't reinvent the wheel. Just give the stream to one of the existing XML-parsing classes, which will perform the appropriate detection for you.

不…忘初心 2024-12-05 12:51:24

您需要将流中的当前位置更改为开头。

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

You need to change the current position in the stream to the beginning.

r.Position = 0;
string text = new StreamReader(r, Encoding.GetEncoding(encoding)).ReadToEnd();
心安伴我暖 2024-12-05 12:51:24

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

如何我可以在 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;
}

I found the answer to my question here:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文