我在尝试使用FileStream将文件上传到我们的SQL DB时有点困难。我已经按照这个例子http://www.codeproject.com/Articles/128657/How-Do-I-Use-SQL-File-Stream,但不同的是我们以10mb块的形式上传文件。
在第一个块上,在DB中创建一条记录,其中包含空内容(以便创建文件),然后为每个块调用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属性的列的更新,该文件然后将全部新数据值写入其中。提交更新后,文件指针会更改为指向新文件,而旧文件将在垃圾回收时删除。这发生在检查点以进行简单恢复,以及备份或日志备份。
那么我是否只是等待垃圾收集器删除分块文件?或者我应该先将文件上传到文件系统的某个位置,然后再将其复制?
答案 0 :(得分:1)
是的,你必须等待Sql为你清理文件。
除非您有其他系统限制,否则您应该能够一次性传输整个文件。这将在sql端为您提供单个文件