65.9K
CodeProject is changing. Read more.
Home

Utilty to split and merge files

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (16 votes)

Nov 25, 2004

CPOL

2 min read

viewsIcon

94900

downloadIcon

2142

A simple C#/.NET utility to split files (upto 2 GB) to parts.

Sample image

Introduction

Well, I was working simultaneously on a USB-less NIC-less desktop and on a CD-less laptop, and I needed the FXCop utility, which was in the desktop, for the laptop. The only possible way to do so was to split it in the desktop, so as to copy its parts to the laptop (none of them is connected to internet), and then merge them back. I went back some years earlier, when I was fond of Borland C and MS DOS, and I wrote a utility in C. I first tried it on a MP3 file in order to test if it works really, then passed to a packaged installer (because it checks integrity of the file), and finally I decided to rewrite it in C#...

Note

The FileSplitter just reads sequentially blocks of 8 Kb or 16 Kb from the file to split, and writes it into the first part file "0.part" in a directory named the same name as the name of the file to split, created in the directory selected using "Browse" button. It writes the first part until it reaches the desired end, then it creates another one "1.part" and so on until it reaches the end of the file to split. For merging, the FileSplitter reads every "part" file in the selected directory and merges them incrementally. It is now done asynchronously using threads. The user can cancel any process (the File/Directory in progress of creation is deleted).

Using the code

Actually, merging was much easier to develop than splitting... I used two file streams the first to point to the file to split and the other to the file The FileSplitter uses a BinayReader and a BinaryWriter to optimize reading and writing a little bit. All the jobs are stored in two methods in one class: the form class.

private bool Splitter(string strFileName,string strPathName,long lgSize)
{
    ...
    prgbProgress.Step = (int) System.Math.Ceiling( ( (float)FileSize / 10 ));

    //split it to parts in a folder Called "FileName"
    System.IO.Directory.CreateDirectory(strDirectory);

    //begin writing
    while ( FSIn.Position != FSIn.Length )
    {
        PreDefinedCacheSize = 8192;
        byte [] buffer = new byte [PreDefinedCacheSize];
        strNewFileNames = strDirectory + "//" + intCounter.ToString() + 
                          ".part" + intCounter.ToString() + ".part";
        FSout = new FileStream(strNewFileNames,FileMode.Create);
        BinaryWriter wFSOut = new BinaryWriter(FSout);
        while ((FSout.Position  < lgSize) && (FSIn.Position != FSIn.Length ))
        {
            prgbProgress.Value = (int) (( (float) FSIn.Position / 
                  (float) FSIn.Length ) * (float) prgbProgress.Maximum);
            if ( ((FSIn.Length - FSIn.Position) < Math.Min(PreDefinedCacheSize, 
                              (int)lgSize)) && (PreDefinedCacheSize > lgSize) )
            {
                PreDefinedCacheSize = (int)FSIn.Length - (int)FSIn.Position;
                rFSIn.Read(buffer,0,PreDefinedCacheSize);
                wFSOut.Write(buffer);
                Thread.Sleep(1);
            }
            else
            {
                if ( PreDefinedCacheSize > lgSize ) PreDefinedCacheSize = (int)lgSize;
                rFSIn.Read(buffer,0,PreDefinedCacheSize);
                wFSOut.Write(buffer);
                Thread.Sleep(1);
            }
        }
        wFSOut.Close();
        FSout.Close();
        intCounter++;
    }
    //finish
    MessageBox.Show("Done!! splitting "+strFileName,"Splitter");
    CleanUp();
    rFSIn.Close();
    return true;
}

void TheSplitter() //the splitter method to be invoked
{
    int SizeLimit = 0;
    if (rdbFree.Checked)
    {
        if (txtSize.TextLength != 0 )SizeLimit = Int32.Parse(txtSize.Text);
        if (rdbKiloBytes.Checked) SizeLimit *= 1024;
        if (rdbMegaBytes.Checked) SizeLimit *= 1024*1024;
    }
    else if (rdbCD.Checked) SizeLimit = CDSize;
    else SizeLimit = FDDSize;
    Splitter(txtFileName.Text,txtFolderPath.Text,SizeLimit);
}
  • FSIn: File stream for the file to split.
  • FSout: File stream for parts.
  • PreDefinedCacheSize: Block size to read and write.
  • void CleanUp(): closes streams, restores the form appearance if a wrong entry was submitted.
  • string FileName(string): returns the file name from a path.
  • bool Merger(string): merges the files in the path given in the string.
  • bool Splitter(string1, string2, long_): Splits the file given in string1 into folder string2 in long_ chunks.
  • void TheSplitter(): Method to invoke the splitter.
  • void TheMerger(): Method to invoke the merger.

History

Some one once said that History is What U made some milliseconds earlier... and so history of human beings was built.