Introduction
I love to do utility programs in .Net. And this is one of them. As I was playing with JSplit (a free file splitter program), I wondered if I could do it in .Net. The framework supports file operations like reading files in bytes and creating them. It is indeed easy to do file operations in .Net.
Basics on File operations
The namespace System.IO provides classes for file operations. StreamReader is a class which provides methods to read a file in different modes. It allows the user to read file by number of characters, by line, by block and to the end of the file. There is another class FileStream which allows the user to read file by number of bytes. This is what we are going to use.
Getting Started
Lets begin by creating a windows application with a textbox, a numericupdown control, a label and three buttons. Add a openfileDialog control and add some code to extract the filename from the dialog and to put it in the textbox when the browse button is clicked.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = openFileDialog1.FileName;
}
Now change the Maximum value of the numericupdown control to 1. Change the backcolor of the label to black and forecolor to green (to give a matrix screen effect).
Set the text property of the buttons to "Calculate" and "Split".
Include the namespaces System.IO and System.Text in the Using section.
Calculate Method
In Calculate method we are going to calculate the number of parts the file will be splitted based on the file size and the split size specified by the user.
Double click on the calculate button to go to the Click event. Now initialize the class FileStream by passing the filename from the textbox and specifying file mode and file access parameters.
FileStream FR = new FileStream(txtFileName.Text, FileMode.Open, FileAccess.Read);
The number of parts is caculated by dividing the file size (in bytes) and user selected split size. This is made to display in the label.
int no_of_parts = Int32.Parse(FR.Length.ToString())/intByteSize;
int intmod=Int32.Parse(FR.Length.ToString())%intByteSize;
//Include the remaining bytes
if(intmod > 0)
no_of_parts=no_of_parts+1;
Split Method
In this method we are going to split the file in to user desired size and number of parts. We again use the FileStream class to read the file. But here we are going to read the file by number of bytes required for each part. So after reading a block of bytes required for a part we write it to a file by using FileStream but in the create file mode and write file access.
//Read the file by number of bytes and create part files
for(int i=0;i<no_of_parts;i++)
{
if(intmod>0 && i==no_of_parts-1)
{
by=new byte[intmod];
FR.Read(by,0,intmod);
}
else
{
by=new byte[intByteSize];
FR.Read(by,0,intByteSize);
}
}
FileStream's WriteByte function is used to write the bytes to a file. Like this number of files are generated for the number of parts calculated. Each file is written with a dynamic name by appending some incrementing number to the file name.
foreach (byte b in by)
{
FW.WriteByte(b);
}
Batch File
The significance of a file splitter is the ability to reunite the file without the actual splitter application. For this, we create a batch file in the split function to reunite the files and create the actual file. This batch file contains statements to combine the part files and generate the actual file.
StringBuilder SB = new StringBuilder();
SB.Append("Copy /b " + tempfilenames + " \"" + filename + "\"");
SW.Write(SB.ToString());
We use StringBuilder class to generate the statement for the batch file. The statement includes the command for uniting the files followed by the filenames. This command should be dynamically added to include the filenames. Now we write this statement to a file and save. The content of the batch file should look like the following statement.
Copy /b "test.pdf0" +"test.pdf1" +"test.pdf2" "test.pdf"
Conclusion
While using file operations we should ensure that the file is closed after the read/write process. Thats all folks!