【问题标题】:How to merge two memory streams?如何合并两个内存流?
【发布时间】:2013-03-17 07:39:39
【问题描述】:

我有两个 MemoryStream 实例。

如何将它们合并为一个实例?

嗯,现在我不能从一个 MemoryStream 复制到另一个。 这是一个方法:

public static Stream ZipFiles(IEnumerable<FileToZip> filesToZip) {
ZipStorer storer = null;
        MemoryStream result = null;
        try {
            MemoryStream memory = new MemoryStream(1024);
            storer = ZipStorer.Create(memory, GetDateTimeInRuFormat());
            foreach (var currentFilePath in filesToZip) {
                string fileName = Path.GetFileName(currentFilePath.FullPath);
                storer.AddFile(ZipStorer.Compression.Deflate, currentFilePath.FullPath, fileName,
                               GetDateTimeInRuFormat());
            }
            result = new MemoryStream((int) storer.ZipFileStream.Length);
            storer.ZipFileStream.CopyTo(result); //Does not work! 
                                               //result's length will be zero
        }
        catch (Exception) {
        }
        finally {
            if (storer != null)
                storer.Close();
        }
        return result;
    }

【问题讨论】:

  • “合并”是什么意思?
  • 这是含糊的。你想做什么?代码示例?
  • 为什么这被否决了?这是非常直观的,-1 Robuust 和 -1 Jon。一个实例是你分配一个类的时候。有问题的对象是一个内存流(它是一个可查找的字节数组,就像内存中的一个文件)。将两个文件放在一个存档文件 (zip) 中是有意义的。将两个文件的位组合成一个看起来像一个的文件,然后能够将它们分开是很容易理解的。这些是你唯一的选择。 p.s.如果没有意义,请给这个人一点更新他们的答案。

标签: c# .net memorystream


【解决方案1】:

使用CopyToCopyToAsync 非常简单:

var streamOne = new MemoryStream();
FillThisStreamUp(streamOne);
var streamTwo = new MemoryStream();
DoSomethingToThisStreamLol(streamTwo);
streamTwo.CopyTo(streamOne); // streamOne holds the contents of both

框架,人。 框架

【讨论】:

  • 确保调整Copy操作的位置,StreamOne位置必须等于它的长度,StreamTwo位置必须为0。
  • 能否避免 streamTwo 克隆/复制以提高性能?
  • 当然。编写一个 Stream 的实现,输出两个或多个子流的内容。
【解决方案2】:

根据上面@Will 分享的答案,这里是完整的代码:

void Main()
{
    var s1 = GetStreamFromString("Hello");
    var s2 = GetStreamFromString(" World");

    var s3 = s1.Append(s2);
    Console.WriteLine(Encoding.UTF8.GetString((s3 as MemoryStream).ToArray()));
}

public static Stream GetStreamFromString(string text)
{
        MemoryStream stream = new MemoryStream();
        StreamWriter writer = new StreamWriter(stream);
        writer.Write(text);
        writer.Flush();
        stream.Position = 0;

        return stream;
}

public static class Extensions
{ 
    public static Stream Append(this Stream destination, Stream source)
    {
        destination.Position = destination.Length;
        source.CopyTo(destination);

        return destination;
    }
}

将流集合与async合并:

async Task Main()
{
    var list = new List<Task<Stream>> { GetStreamFromStringAsync("Hello"), GetStreamFromStringAsync(" World") };

    Stream stream = await list
            .Select(async item => await item)
            .Aggregate((current, next) => Task.FromResult(current.Result.Append(next.Result)));

    Console.WriteLine(Encoding.UTF8.GetString((stream as MemoryStream).ToArray()));
}

public static Task<Stream> GetStreamFromStringAsync(string text)
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(text);
    writer.Flush();
    stream.Position = 0;

    return Task.FromResult(stream as Stream);
}

public static class Extensions
{
    public static Stream Append(this Stream destination, Stream source)
    {
        destination.Position = destination.Length;
        source.CopyTo(destination);

        return destination;
    }
}

【讨论】:

    【解决方案3】:
    • 创建第三个(让它成为mergedStreamMemoryStream 和长度 等于第一和第二长度之和

    • 先写MemoryStreammergedStream(使用GetBuffer()到 从MemoryStream获取byte[])

    • 将第二个MemoryStream 写入mergedStream(使用GetBuffer()

    • 在写入时记住偏移量。

    它是 append,但完全不清楚 MemoryStreams 上的合并操作是什么

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-30
      • 2018-05-02
      • 1970-01-01
      • 2014-05-23
      • 2019-03-05
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      相关资源
      最近更新 更多