简体   繁体   English

将大文件流式传输到数据库BLOB字段中

[英]Streaming a large file into a database BLOB field

I have a large file on disk whose contents I need to store in a SqlServer database as a VARBINARY(MAX) field. 我在磁盘上有一个大文件,其内容需要作为VARBINARY(MAX)字段存储在SqlServer数据库中。 By "contents", I mean using something like File.ReadAllBytes() . File.ReadAllBytes() “内容”是指使用File.ReadAllBytes()类的东西。 (I understand the pitfalls of this, but it's the current mode of operations, so I have to deal with it for now.) (我了解这方面的陷阱,但这是当前的操作模式,因此我现在必须处理它。)

I found this answer, which provides a way to stream a large Byte[] by using UPDATE.WRITE : 我找到了这个答案,它提供了一种使用UPDATE.WRITE流大Byte[]的方法:

How to I serialize a large graph of .NET object into a SQL Server BLOB without creating a large buffer? 如何在不创建大缓冲区的情况下将.NET对象的大图序列化为SQL Server BLOB?

However, simply reading the contents of a large file into a Byte[] in memory leads to this problem: 但是,仅将大文件的内容读取到内存中的Byte[]中会导致此问题:

OutOfMemoryException when I read 500MB FileStream 读取500MB FileStream时出现OutOfMemoryException

I might be overlooking something obvious, but I just can't work out how should I go about getting from a large file on disk, to the resulting storage into the database. 我可能忽略了一些显而易见的事情,但是我无法弄清楚应该如何从磁盘上的大文件获取最终存储到数据库中。

Using some hints I got from these two pages, I have an answer that works: 使用从这两页获得的一些提示,我得到了一个可行的答案:

http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/ (this looks a lot like the serialize SO answer, but there's more here...not sure who copied who!). http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/ (这看起来很像序列化的SO答案,但是这里还有更多...不确定谁复制了谁!)。

How do I copy the contents of one stream to another? 如何将一个流的内容复制到另一个?

Basically, it uses the same methodology as the answer about serializing Blobs, but instead of using BinaryFormatter (a class I'm not fond of anyhow), it creates a FileStream that takes the path to the file, and an extension method to copy that stream into the target stream, or BlobStream , as the example named it. 基本上,它使用与序列化Blob的答案相同的方法,但不是使用BinaryFormatter (无论如何我都不喜欢的类),而是创建一个FileStream来获取文件路径,并使用扩展方法来复制该文件。流命名为目标流,即BlobStream ,如其示例所示。

Here's the extension: 这是扩展名:

public static class StreamEx
{
    public static void CopyTo(this Stream Input, Stream Output)
    {
        var buffer = new Byte[32768];
        Int32 bytesRead;
        while ((bytesRead = Input.Read(buffer, 0, buffer.Length)) > 0)
            Output.Write(buffer, 0, bytesRead);
    }
}

So the trick was to link two streams, copying the data from one to another in chunked fashion, as noted in the comments. 因此,技巧是链接两个流,将数据以分块的方式从一个流复制到另一个流,如注释中所述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM