0

我在尝试使用 FileStream 将文件上传到我们的 SQL DB 时有点卡住了。我已经按照这个例子http://www.codeproject.com/Articles/128657/How-Do-I-Use-SQL-File-Stream但不同的是我们以 10mb 块上传文件。

在第一个块上,在数据库中创建一个内容为空的记录(以便创建一个文件),然后为每个块调用 OnUploadChunk。

该文件正在上传,但是当我检查时,已经为每个块创建了一个新文件,因此对于一个 20mb 的文件,我有一个 0kb,另一个是 10mb,最后一个是 20mb。我期待一个20mb的文件。

我猜这可能与获取事务上下文或错误地使用我还没有完全掌握的 TransactionScope 有关。我认为这对于每个块可能会有所不同,因为它往返于客户端和服务器之间。

这是每次从客户端发送块时调用的方法(如果有任何相关性,则使用 PlupLoad)。

protected override bool OnUploadChunk(Stream chunkStream, string DocID)
{
    BinaryReader b = new BinaryReader(chunkStream);
    byte[] binData = b.ReadBytes(chunkStream.Length);

        using (TransactionScope transactionScope = new TransactionScope())
        {

            string FilePath = GetFilePath(DocID); (Folder path the file is sitting in)

            //Gets size of file that has been uploaded so far
            long currentFileSize = GetCurrentFileSize(DocID)

            //Essentially this is just Select GET_FILESTREAM_TRANSACTION_CONTEXT()
            byte[] transactionContext = GetTransactionContext();

            SqlFileStream filestream = new SqlFileStream(FilePath, transactionContext, FileAccess.ReadWrite);

            filestream.Seek(currentFileSize, SeekOrigin.Begin);
            filestream.Write(binData, 0, (int)chunkStream.Length);
            filestream.Close();
            transactionScope.Complete(); 
          }
}

更新:

我做了一些研究,我相信这个问题是围绕着这个:

FILESTREAM 目前不支持就地更新。因此,通过创建一个新的零字节文件来实现对具有 FILESTREAM 属性的列的更新,然后将整个新数据值写入该文件。提交更新后,文件指针将更改为指向新文件,而旧文件将在垃圾收集时被删除。这发生在简单恢复的检查点以及备份或日志备份中。

那么我是否只需要等待垃圾收集器删除分块文件?或者我应该先将文件上传到文件系统的某个位置,然后再复制它?

4

1 回答 1

1

是的,您将不得不等待 Sql 为您清理文件。

除非您有其他系统限制,否则您应该能够一次流式传输整个文件。这将为您提供 sql 端的单个文件

于 2014-03-28T15:44:50.967 回答