将内存流复制到文件流并保存文件?

50

我不明白在这里做错了什么。我生成了一些内存流,并在调试模式下看到它们被填充了。但是当我尝试将 MemoryStream 复制到 FileStream 以便保存文件时,fileStream 没有被填充,文件大小为0字节(空的)。

以下是我的代码:

if (file.ContentLength > 0)
{
    var bytes = ImageUploader.FilestreamToBytes(file); // bytes is populated

    using (var inStream = new MemoryStream(bytes)) // inStream is populated
    {
        using (var outStream = new MemoryStream())
        {
            using (var imageFactory = new ImageFactory())
            {
                imageFactory.Load(inStream)
                            .Resize(new Size(320, 0))
                            .Format(ImageFormat.Jpeg)
                            .Quality(70)
                            .Save(outStream);
            }
            
            // outStream is populated here
            
            var fileName = "test.jpg";

            using (var fileStream = new FileStream(Server.MapPath("~/content/u/") + fileName, FileMode.CreateNew, FileAccess.ReadWrite))
            {
                outStream.CopyTo(fileStream); // fileStream is not populated
            }
        }
    }
}

你确定outStream包含图像数据吗?我认为问题在.Save(outStream);你能否提供调用堆栈。 - Bassam Alugili
1
@BassamAlugili,我已经在调试模式下检查过了。它是有值的。outStream.Position = 0 是问题所在,我需要设置它。 - Stan
3个回答

74

在复制之前,您需要重置流的位置。

outStream.Position = 0;
outStream.CopyTo(fileStream);

在使用imageFactory保存文件时,您使用了outStream。该函数填充了outStream。在填充outStream时,该位置设置为填充区域的末尾。这样,当您继续写入流时,它不会覆盖现有的字节。但是,为了读取它(进行复制),您需要将位置设置为开头,以便可以从开头开始读取。


我在想他为什么需要这个Position = 0;他只是创建了outStream但没有使用;为什么他会得到错误的位置呢? - Bassam Alugili
7
@BassamAlugili 在使用 imageFactory 保存文件时使用了 outsteam。该函数填充了 outsteam。在填充 outsteam 时,位置被设置在已填充区域的末尾。这样当你继续向 steam 写入字节时,就不会覆盖现有的字节。但是,如果想要读取它(用于复制),则需要将位置设置为开头,这样就可以从开头开始阅读了。 - SynerCoder

21

2
你不需要使用 memoryStream.Position = 0;MemoryStream.ToArray() 显式忽略 Position - Bacon Bits

5

使用WriteToCopyTo的另一种选择。

优点:

无需重置位置。

用法:

outStream.WriteTo(fileStream);                

功能描述:

将该内存流的全部内容写入到另一个流中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接