Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何读取流并将其位置重置为零,即使Stream.CanSeek==false_C#_.net - Fatal编程技术网

C# 如何读取流并将其位置重置为零,即使Stream.CanSeek==false

C# 如何读取流并将其位置重置为零,即使Stream.CanSeek==false,c#,.net,C#,.net,如何读取流并将其位置重置为零,即使Stream.CanSeek==false?我需要一些解决方法。使用另一个支持查找的流实现。如果Stream.CanSeek返回false,则该实现声明它不支持查找 MemoryStream对象不支持查找。您可以使用类似的方法将任意流复制到MemoryStream,生成的流将支持查找,例如,您可以将位置重置为0并重复读取 MemoryStream CopyStreamToMemory(Stream inputStream) { MemoryStream

如何读取流并将其位置重置为零,即使
Stream.CanSeek==false
?我需要一些解决方法。

使用另一个支持查找的流实现。如果
Stream.CanSeek
返回false,则该实现声明它不支持查找

MemoryStream
对象不支持查找。您可以使用类似的方法将任意流复制到MemoryStream,生成的流将支持查找,例如,您可以将位置重置为0并重复读取

MemoryStream CopyStreamToMemory(Stream inputStream)
{
    MemoryStream ret = new MemoryStream();
    const int BUFFER_SIZE = 1024;
    byte[] buf = new byte[BUFFER_SIZE];

    int bytesread = 0;
    while ((bytesread = inputStream.Read(buf, 0, BUFFER_SIZE)) > 0)
        ret.Write(buf, 0, bytesread);

    ret.Position = 0;
    return ret;
}

当然,如果您的流读取的数据没有变化,您可以简单地处理旧流,并创建一个读取相同数据的新流。

如果您的场景允许您替换原始流,那么您可以检查它是否支持查找,如果不支持,则读取其内容并将其包装到新的
内存流中,然后可以用于后续操作

static string PeekStream(ref Stream stream)
{
    string content;
    var reader = new StreamReader(stream);
    content = reader.ReadToEnd();

    if (stream.CanSeek)
    {
        stream.Seek(0, SeekOrigin.Begin);
    }
    else
    {
        stream.Dispose();
        stream = new MemoryStream(Encoding.UTF8.GetBytes(content));
    }

    return content;
}
上述方法效率相当低,因为它必须为内容大小的两倍分配内存。我的建议是修改代码中访问流的部分(在读取了流的所有内容之后),以便让它们访问存储的内容副本。例如:

string content;
using (var reader = new StreamReader(stream))
    content = reader.ReadToEnd();

// Process content here.

string line;
using (var reader = new StringReader(content))
    while ((line = reader.ReadLine()) != null)
        Console.WriteLine(line);

由于
StringReader
只读取您的
内容
字符串,因此您不会浪费内存创建数据的冗余副本。

如果
CanSeek==false
,任何此类尝试都可能导致异常。@oded;我知道,;这就是为什么我会问这样一个问题:在你有非常大的数据之前,这种方法是正确的。如果您有一些千兆字节,那么最好重新初始化您的流。在我看来,流式处理的目的不是存储您正在处理的所有数据。您关于
MemoryStream
不适合大数据的说法是正确的。存储还是重新初始化流取决于场景。例如,如果您正在处理从Internet下载的数据,并且需要多次读取,则最好将数据存储在本地(内存或临时文件中),而不是再次下载。