/// <inheritdoc /> public async Task <long> AppendDataAsync(string fileId, Stream stream, CancellationToken cancellationToken) { var path = GetPath(fileId); long bytesWritten = 0; var uploadLength = await GetUploadLengthAsync(fileId, cancellationToken); using (var file = File.Open(path, FileMode.Append, FileAccess.Write)) { var fileLength = file.Length; if (uploadLength == fileLength) { return(0); } var chunkStart = _fileRepFactory.ChunkStartPosition(fileId); var chunkComplete = _fileRepFactory.ChunkComplete(fileId); if (chunkComplete.Exist()) { chunkStart.Delete(); chunkComplete.Delete(); } if (!chunkStart.Exist()) { chunkStart.Write(fileLength.ToString()); } int bytesRead; do { if (cancellationToken.IsCancellationRequested) { break; } var buffer = new byte[ByteChunkSize]; bytesRead = await stream.ReadAsync(buffer, 0, ByteChunkSize, cancellationToken); fileLength += bytesRead; if (fileLength > uploadLength) { throw new TusStoreException( $"Stream contains more data than the file's upload length. Stream data: {fileLength}, upload length: {uploadLength}."); } file.Write(buffer, 0, bytesRead); bytesWritten += bytesRead; } while (bytesRead != 0); // Chunk is complete. Mark it as complete. chunkComplete.Write("1"); return(bytesWritten); } }
/// <inheritdoc /> public Task DeleteFileAsync(string fileId, CancellationToken cancellationToken) { var internalFileId = new InternalFileId(fileId); return(Task.Run(() => { _fileRepFactory.Data(internalFileId).Delete(); _fileRepFactory.UploadLength(internalFileId).Delete(); _fileRepFactory.Metadata(internalFileId).Delete(); _fileRepFactory.UploadConcat(internalFileId).Delete(); _fileRepFactory.Expiration(internalFileId).Delete(); _fileRepFactory.ChunkStartPosition(internalFileId).Delete(); _fileRepFactory.ChunkComplete(internalFileId).Delete(); }, cancellationToken)); }
/// <inheritdoc /> public async Task DeleteFileAsync(string fileId, CancellationToken _) { var internalFileId = await InternalFileId.Parse(_fileIdProvider, fileId); await Task.Run(() => { _fileRepFactory.Data(internalFileId).Delete(); _fileRepFactory.UploadLength(internalFileId).Delete(); _fileRepFactory.Metadata(internalFileId).Delete(); _fileRepFactory.UploadConcat(internalFileId).Delete(); _fileRepFactory.ChunkStartPosition(internalFileId).Delete(); _fileRepFactory.ChunkComplete(internalFileId).Delete(); _fileRepFactory.Expiration(internalFileId).Delete(); }); }
/// <inheritdoc /> public async Task <long> AppendDataAsync(string fileId, Stream stream, CancellationToken cancellationToken) { var internalFileId = new InternalFileId(fileId); var reciveReadBuffer = new byte[_maxReadBufferSize]; long bytesWritten = 0; var uploadLength = await GetUploadLengthAsync(fileId, cancellationToken); using (var writeBuffer = new MemoryStream(_maxWriteBufferSize)) using (var file = _fileRepFactory.Data(internalFileId).GetStream(FileMode.Append, FileAccess.Write, FileShare.None)) { var fileLength = file.Length; if (uploadLength == fileLength) { return(0); } var chunkStart = _fileRepFactory.ChunkStartPosition(internalFileId); var chunkComplete = _fileRepFactory.ChunkComplete(internalFileId); if (chunkComplete.Exist()) { chunkStart.Delete(); chunkComplete.Delete(); } if (!chunkStart.Exist()) { chunkStart.Write(fileLength.ToString()); } int bytesRead; do { if (cancellationToken.IsCancellationRequested) { break; } bytesRead = await stream.ReadAsync(reciveReadBuffer, 0, _maxReadBufferSize, cancellationToken); fileLength += bytesRead; if (fileLength > uploadLength) { throw new TusStoreException( $"Stream contains more data than the file's upload length. Stream data: {fileLength}, upload length: {uploadLength}."); } writeBuffer.Write(reciveReadBuffer, 0, bytesRead); bytesWritten += bytesRead; // If the buffer is above max size we flush it now. if (writeBuffer.Length >= _maxWriteBufferSize) { await FlushFileWriteBuffer(writeBuffer, file); } } while (bytesRead != 0); // Flush the remaining buffer to disk. if (writeBuffer.Length != 0) { await FlushFileWriteBuffer(writeBuffer, file); } if (!cancellationToken.IsCancellationRequested) { // Chunk is complete. Mark it as complete. chunkComplete.Write("1"); } return(bytesWritten); } }