/// <summary> /// original name + ".part_N.X" (N = file part number, X = total files) /// Objective = enumerate files in folder, look for all matching parts of split file. If found, merge and return true. /// </summary> /// <param name="FileName"></param> /// <returns></returns> public bool MergeFile(string FileName) { bool rslt = false; // parse out the different tokens from the filename according to the convention string partToken = ".part_"; string baseFileName = FileParts[0].Substring(0, FileParts[0].IndexOf(partToken)); string trailingTokens = FileParts[0].Substring(FileParts[0].IndexOf(partToken) + partToken.Length); int FileIndex = 0; int FileCount = 0; int.TryParse(trailingTokens.Substring(0, trailingTokens.IndexOf(".")), out FileIndex); int.TryParse(trailingTokens.Substring(trailingTokens.IndexOf(".") + 1), out FileCount); // get a list of all file parts in the temp folder string Searchpattern = Path.GetFileName(baseFileName) + partToken + "*"; string[] FilesList = Directory.GetFiles(Path.GetDirectoryName(OrignalFileName), Searchpattern); // merge .. improvement would be to confirm individual parts are there / correctly in sequence, a security check would also be important // only proceed if we have received all the file chunks if (FilesList.Count() == FileCount) { // use a singleton to stop overlapping processes if (!MergeFileManager.Instance.InUse(baseFileName)) { MergeFileManager.Instance.AddFile(baseFileName); if (File.Exists(baseFileName)) { File.Delete(baseFileName); } // add each file located to a list so we can get them into // the correct order for rebuilding the file List <SortedFile> MergeList = new List <SortedFile>(); foreach (string File in FilesList) { SortedFile sFile = new SortedFile(); sFile.FileName = File; baseFileName = File.Substring(0, File.IndexOf(partToken)); trailingTokens = File.Substring(File.IndexOf(partToken) + partToken.Length); int.TryParse(trailingTokens.Substring(0, trailingTokens.IndexOf(".")), out FileIndex); sFile.FileOrder = FileIndex; MergeList.Add(sFile); } // sort by the file-part number to ensure we merge back in the correct order var MergeOrder = MergeList.OrderBy(s => s.FileOrder).ToList(); using (FileStream FS = new FileStream(baseFileName, FileMode.Create)) { // merge each file chunk back into one contiguous file stream foreach (var chunk in MergeOrder) { try { using (FileStream fileChunk = new FileStream(chunk.FileName, FileMode.Open)) { fileChunk.CopyTo(FS); } } catch (IOException ex) { // handle } } } rslt = true; // unlock the file from singleton MergeFileManager.Instance.RemoveFile(baseFileName); } } foreach (var filePart in FileParts) { if (File.Exists(filePart)) { File.Delete(filePart); } } return(rslt); }
public bool MergeFile(string FileName) { bool rslt = false; string partToken = ".part_"; string baseFileName = FileName.Substring(0, FileName.IndexOf(partToken)); string trailingTokens = FileName.Substring(FileName.IndexOf(partToken) + partToken.Length); int FileIndex = 0; int FileCount = 0; int.TryParse(trailingTokens.Substring(0, trailingTokens.IndexOf(".")), out FileIndex); int.TryParse(trailingTokens.Substring(trailingTokens.IndexOf(".") + 1), out FileCount); string Searchpattern = Path.GetFileName(baseFileName) + partToken + "%"; try { var CS = System.Configuration.ConfigurationManager.AppSettings["DBConnectionString"]; var FilesList = new List <string>(); using (SqlConnection connection = new SqlConnection()) { connection.ConnectionString = CS; connection.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = connection; cmd.CommandTimeout = 0; string commandText = "select f_name from t_files_temp where f_name like '" + Searchpattern + "'"; cmd.CommandText = commandText; cmd.CommandType = System.Data.CommandType.Text; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { FilesList.Add(reader.GetString(0)); } } connection.Close(); } //string[] FilesList = Directory.GetFiles(Path.GetDirectoryName(FileName), Searchpattern); if (FilesList.Count == FileCount) { if (!MergeFileManager.Instance.InUse(baseFileName)) { MergeFileManager.Instance.AddFile(baseFileName); List <SortedFile> MergeList = new List <SortedFile>(); foreach (string File in FilesList) { SortedFile sFile = new SortedFile(); sFile.FileName = File; baseFileName = File.Substring(0, File.IndexOf(partToken)); trailingTokens = File.Substring(File.IndexOf(partToken) + partToken.Length); int.TryParse(trailingTokens.Substring(0, trailingTokens.IndexOf(".")), out FileIndex); sFile.FileOrder = FileIndex; MergeList.Add(sFile); } var MergeOrder = MergeList.OrderBy(s => s.FileOrder).ToList(); using (SqlConnection connection = new SqlConnection()) { connection.ConnectionString = CS; connection.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = connection; cmd.CommandTimeout = 0; string commandText = "INSERT INTO t_files VALUES('" + baseFileName + "', (SELECT CAST(f_binarystring AS varchar(MAX)) FROM t_files_temp WHERE f_basename = '" + baseFileName + "' ORDER BY f_id FOR xml PATH('') ) ); ; "; cmd.CommandText = commandText; cmd.CommandType = System.Data.CommandType.Text; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { FilesList.Add(reader.GetString(0)); } } connection.Close(); } rslt = true; MergeFileManager.Instance.RemoveFile(baseFileName); WebApplication6.Controllers.HomeController.UploadComplete(baseFileName); } } return(rslt); } catch (Exception ex) { } return(rslt); }