public async Task AddChunkFile(long userId, byte[] chunk, FlowUploadForm flow) { string filename = _createChunkFile(userId, flow.flowChunkNumber, flow.flowIdentifier); for (int i = 1; i <= NumberOfRetries; ++i) { try { using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Write)) { await fs.WriteAsync(chunk, 0, chunk.Length); fs.Flush(); fs.Dispose(); } break; } catch (IOException e) { if (i == NumberOfRetries) { throw; } Thread.Sleep(DelayOnRetry); } } }
private void _deleteChunkFiles(long userId, FlowUploadForm flow) { for (int chunkNumber = 1; chunkNumber <= flow.flowTotalChunks; chunkNumber++) { var chunkFileName = _getChunkFileName(userId, chunkNumber, flow.flowIdentifier); File.Delete(chunkFileName); } }
public async Task <IActionResult> MovieUpload(FlowUploadForm flow, NewMovieForm newMovie) { var userId = TokenManager.ExtractUserId(User.Claims); try { foreach (var formFile in Request.Form.Files) { using (var readStream = formFile.OpenReadStream()) using (var binaryReader = new BinaryReader(readStream)) { var fileContent = binaryReader.ReadBytes((int)formFile.Length); await _uploadService.AddChunkFile(userId, fileContent, flow); } if (_uploadService.AttemptCompleteFileCreation(userId, flow, formFile.FileName, out FileMetadata metadata)) { newMovie.ResolveMovieImage(_externalDB); metadata.GetDuration(new MediaManager()); var movieEntity = newMovie.MapToEntity(userId, metadata.MapToVideoFileEntity()); movieEntity.DateCreated = DateTime.Now; movieEntity = _movieRpository.Add(movieEntity); //If file is not mp4. it cannot be streamed properly to a browser so convert it //This process takes a while. Consider moveing this out of the flow if (movieEntity.VideoFile.FileExtension != ".mp4") { _videoConverter.AddVideoToQueue(movieEntity.VideoFile); } return(Created($"api/movies/{movieEntity.MovieId}", MovieResponse.MapFromObject(movieEntity))); } } } catch { return(StatusCode(500, "There was an Error Uploading the File")); } return(Ok()); }
public bool AttemptCompleteFileCreation(long userId, FlowUploadForm flow, string filename, out FileMetadata fileinfo) { if (_allChunksArrived(userId, flow.flowTotalChunks, flow.flowIdentifier)) { var tempFileName = _combineChunkFiles(userId, flow); var finalFilename = _createFinalPath(userId, filename); finalFilename = FileMetadata.VerifyFileUniqueness(finalFilename); File.Move(tempFileName, finalFilename); _deleteChunkFiles(userId, flow); fileinfo = new FileMetadata(finalFilename); return(true); } //File not yet ready to be reconstituted fileinfo = null; return(false); }
private string _combineChunkFiles(long userId, FlowUploadForm flow) { var tempFileName = Path.Combine(root, "temp", userId.ToString(), flow.flowIdentifier); for (int i = 1; i <= NumberOfRetries; ++i) { try { using (var destStream = File.Create(tempFileName, 15000)) { for (int chunkNumber = 1; chunkNumber <= flow.flowTotalChunks; chunkNumber++) { var chunkFileName = _getChunkFileName(userId, chunkNumber, flow.flowIdentifier); using (var sourceStream = File.OpenRead(chunkFileName)) { sourceStream.CopyTo(destStream); } } } break; } catch (IOException e) { // You may check error code to filter some exceptions, not every error // can be recovered. if (i == NumberOfRetries) // Last one, (re)throw exception and exit { throw; } Thread.Sleep(DelayOnRetry); } } return(tempFileName); }