Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The FileSplitter reLoaded

0.00/5 (No votes)
11 Aug 2008 1  
Utilty to quickly split and merge files.

Sample Image - TheFileSplitterv2Processing.jpg

Introduction

Everybody needs at least twice a file splitter utility. One day I created my own just to do the things to be done :), and then I realized that I could make it run much faster (the FileSPlitter v0.1 runs @ 1~2bytes/hour ^_^), so I inserted some multithreading, some event handling, enlarged the cache used, and of course, rewrote the split and merge methods. Now, it's quite fast: up to 20 Mb/s.

Note

The file splitter is now in a separate class, exposing different commented constructors, methods, and properties. It is disposable and gives the speed of the processing.

Using the code

Just instantiate the FileSplitter, manage its events, and begin processing.

FileSplitter.Splitter fs = new FileSplitter.Splitter(dlgOpen.FileName, 
                           dlgSaveTo.SelectedPath, CacheSize, SizeLimit);

fs.SplitDone += new EventHandler(fs_SplitDone);
fs.partialSplitDone += new EventHandler(fs_partialSplitDone);
fs.SplitError += new EventHandler(fs_SplitError);
fs.BeginSplit();

The Split method is private to the FileSplitter class:

private void Split()
{
    if (m_CacheSize > m_SizeLimit)
        m_CacheSize = (uint)m_SizeLimit;

    byte[] cBuffer = new byte[m_CacheSize];
    int nCounter = 0;

    m_fsIn = new FileStream(m_FileName, FileMode.Open, FileAccess.Read);
    m_bReader = new BinaryReader(m_fsIn);


    if (!Directory.Exists(m_OutDir))
    Directory.CreateDirectory(m_OutDir);
    else
    {
        Directory.Delete(m_OutDir, true);
            Directory.CreateDirectory(m_OutDir);
    }

    int reads = 0;
    try
    {
        do
        {
            m_fsOut = new FileStream(m_OutDir + "\\" + 
                      nCounter.ToString() + ".part", FileMode.Create);
            do
            {
                if ((m_fsIn.Length - m_fsIn.Position) < cBuffer.Length)
                    cBuffer = new byte[m_fsIn.Length - m_fsIn.Position];
                reads = m_bReader.Read(cBuffer, 0, cBuffer.Length);
                m_bWriter = new BinaryWriter(m_fsOut);
                m_bWriter.Write(cBuffer, 0, reads);
                m_Written += reads;// = fsIn.Position;
                m_Progress = (uint)((float)m_Written * 100 / (float)m_FileSize);
                OnPartialSplitDone(EventArgs.Empty);
            } while ((m_fsOut.Position < m_SizeLimit) && 
                     (m_fsIn.Position < m_FileSize));
            m_bWriter.BaseStream.Close();
            m_Written = m_fsIn.Position;
            nCounter++;
            m_Progress = (uint)((float)m_Written * 100 / (float)m_FileSize);
            OnPartialSplitDone(EventArgs.Empty);
        } while ((m_fsIn.Position < m_fsIn.Length));
        m_bReader.BaseStream.Close();
        OnSplitDone(EventArgs.Empty);
    }
    catch (Exception e)
    {
        m_SplitErrorMessage = e.Message;
        OnError(EventArgs.Empty);
        abort();
    }
    GC.Collect();
}
.
.
.

public void BeginMerge()
{
    m_tdMerger = new Thread(new ThreadStart(merge));
    m_tdMerger.Priority = ThreadPriority.AboveNormal;
    m_tdMerger.IsBackground = false;
    m_tdMerger.Name = "Merging";
    m_TimeStart = DateTime.Now;
    m_tdMerger.Start();
}

Methods

  • public FileSplitter(string FileName, string DestinationFolder, int CacheSize, int SizeLimit): Fully qualified constructor - Splitting.
  • public FileSplitter(string FileName, string DestinationFolder, int SizeLimit): Constructor with default cache - Splitting.
  • public FileSplitter(string SourceFolder, int CacheSize): Fully qualified constructor - Merging.
  • public FileSplitter(string SourceFolder): Constructor with default cache - Merging.
  • public void Dispose(): Disposes the class instance.
  • public void BeginMerge(): Begins the merging thread.
  • public void BeginSplit(): Begins the splitting thread.

Events

  • public event EventHandler partialCopyDone: Triggered when a partial processing is done.
  • public event EventHandler CopyDone;: Triggered when processing is done.
  • public event EventHandler Error;: Triggered when an error occurs.

Properties

  • public string ErrorMessage: Last error message
  • public int Progress: Percentage of the entire progress (nice to use with a progress bar).
  • public long TotalDone: Total size processed.

History

  • v2.1: Final version, with real classes, events, and multithreading.
  • V2.0: Events, multithreading, nicer and smoother.
  • v0.1: The beginning.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here