2013-11-10 5 views
0

Я немного застреваю в попытке загрузить файлы в нашу базу данных SQL с помощью FileStream. Я следовал этому примеру http://www.codeproject.com/Articles/128657/How-Do-I-Use-SQL-File-Stream, но разница заключается в том, что мы загружаем файл в куски 10 МБ.SQLFileStream с файлом chunked

На первом фрагменте в БД создается запись с пустым содержимым (так что создается файл), а затем для каждого фрагмента вызывается OnUploadChunk.

Файл загружается нормально, но когда я проверяю, для каждого фрагмента создается новый файл, поэтому для файла 20 Мбайт, например, у меня есть 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(); 
      } 
} 

UPDATE:

Я сделал небольшое исследование, и я считаю, что вопрос вокруг этого:

FILESTREAM не поддерживает обновления на месте. Поэтому обновление столбца с атрибутом FILESTREAM выполняется путем создания нового файла с нулевым байтом, который затем имеет все новое значение данных, записанное на него. Когда обновление зафиксировано, указатель файла затем изменяется, чтобы указать на новый файл, в результате чего старый файл будет удален во время сбора мусора. Это происходит на контрольной точке для простого восстановления и резервного копирования или резервного копирования журнала.

Так что я просто должен дождаться сборщика мусора, чтобы удалить фрагментированные файлы? Или я должен сначала загрузить файл где-нибудь в файловой системе, а затем скопировать его?

ответ

1

Да, вам придется подождать, пока Sql очистит файлы для вас.

Если у вас нет других системных ограничений, вы должны иметь возможность передавать весь файл за один раз. Это даст вам один файл на стороне sql

Смежные вопросы