Using StreamReader/StreamWriter or not to use them
This is outdated version, see Corrections and Questions for current version
/*
* For learning purpose of functions FromBase64CharArray and ToBase64CharArray, I made following
* simple UUEncoder/UUDecoder test case program. There is two implementations of decoder/encoder.
*
* Overall differencies between implementations are as following:
*
* Implementation One is taken from Microsotf's sample.
* EncoderOne uses FileStream for input and StreamWriter for output phase.
* DecoderOne uses StreamReader for input and FileStream for output phase.
*
* Implementation Two is by mostly developed by me.
* EncoderTwo and DecoderTwo uses FileStream for both the input and the output phase.
* Besides that, the both routines use small working buffers.
*
* I have three questions conserning the implementations:
*
* 1. Which one algorithm is better and why?
*2. What is optimal input buffer size for EncoderTwo and DecoderTwo?
* ( see the buffer size requirements / dependies in the code)
*3. Is there more terse or simple implementations avaible?
*
* Regards
* Peca
*/
using
System;using
System.IO;using
System.Text;namespace
base64{
classProgram{
publicstaticvoid DecoderOne(string inputFileName,string outputFileName){
StreamReader inFile;long rdlen = 0;char[] base64CharArray;try {inFile =
newStreamReader(inputFileName,Encoding.ASCII);rdlen = inFile.BaseStream.Length;
base64CharArray =
newchar[rdlen]; // WHAT IS UPPER BOUND FOR THIS TO WORK?inFile.Read(base64CharArray, 0, (int)rdlen);
inFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or reading from it.
Console.WriteLine("{0}", exp.Message);return;}
// Convert the Base64 UUEncoded input into binary output.byte[] binaryData;try {binaryData =
Convert.FromBase64CharArray( base64CharArray,0,
base64CharArray.Length);
}
catch (ArgumentNullException ) {Console.WriteLine("Base 64 character array is null.");return;}
catch ( System.FormatException ) {Console.WriteLine("Base 64 Char Array length is not " +"4 or is not an even multiple of 4." );return;}
// Write out the decoded data.FileStream outFile;try {outFile =
newFileStream(outputFileName,FileMode.Create,FileAccess.Write);outFile.Write( binaryData, 0, binaryData.Length );
outFile.Close();
Console.WriteLine("DecoderOne: {0} bytes read and {1} bytes written", rdlen, binaryData.Length );}
catch (System.Exception exp) {// Error creating stream or writing to it.Console.WriteLine("{0}", exp.Message);}
}
publicstaticvoid EncoderOne(string inputFileName,string outputFileName ){
// Read in the binary data.FileStream inFile;byte[] binaryData =null;char[] base64CharArray =null;long rdlen = 0;try{
inFile =
newFileStream( inputFileName,FileMode.Open,FileAccess.Read );rdlen = inFile.Length;
binaryData =
newbyte[rdlen]; // WHAT IS UPPER BOUND FOR THIS TO WORK?base64CharArray =
newchar[2 * rdlen];inFile.Read( binaryData, 0, (
int ) rdlen );inFile.Close();
}
catch (FileNotFoundException ){
Console.WriteLine("Input file does not exist." );return;}
catch (Exception e ){
Console.WriteLine("{0}", e.Message );return;}
int charCount;try{
charCount =
Convert.ToBase64CharArray( binaryData, 0, binaryData.Length, base64CharArray, 0 );}
catch (ArgumentNullException ){
Console.WriteLine("Base 64 character array is null." );return;}
catch (FormatException ){
Console.WriteLine("Base 64 Char Array length is not " +"4 or is not an even multiple of 4." );return;}
StreamWriter outFile;try{
outFile =
newStreamWriter(outputFileName,false,Encoding.ASCII);outFile.Write( base64CharArray, 0, charCount );
outFile.Close();
Console.WriteLine("EncoderOne: {0} bytes read and {1} bytes written", rdlen, charCount );}
catch (Exception e ){
// Error creating stream or writing to it.Console.WriteLine("{0}", e.Message );return;}
}
privatestaticvoid DecoderTwo(String inName,String outName){
//Create the file streams to handle the input and output files.FileStream fin =null, fout =null;try{
fin =
newFileStream( inName,FileMode.Open,FileAccess.Read );fout =
newFileStream( outName,FileMode.OpenOrCreate,FileAccess.Write );}
catch (FileNotFoundException e ){
Console.WriteLine( e.Message );return;}
catch (Exception e ){
Console.WriteLine( e.Message );fin.Close();
return;}
fout.SetLength( 0 );
constint binmult = 9;constint binsize = 32 * binmult;
constint binmed = 24 * binmult;
//
// Buffer size requirements://byte[] buff_in =newbyte[binsize];char[] buff_med =newchar[binmed];byte[] buff_out =newbyte[binmed];long rdlen = 0;long rtlen = 0;long totlen = fin.Length;int len;try{
while ( rdlen < totlen ){
len = fin.Read( buff_in, 0, binsize );
//--for (int x = 0 ; x < len ; x++ ){
buff_med[x] =
Convert.ToChar( buff_in[x] );}
buff_out =
Convert.FromBase64CharArray( buff_med, 0, len );fout.Write( buff_out, 0, buff_out.Length );
rdlen += len;
rtlen += buff_out.Length;
}
Console.WriteLine("DecoderTwo: {0} bytes read and {1} bytes written", rdlen, rtlen );}
catch (FormatException e ){
Console.WriteLine( e.Message );}
catch (IndexOutOfRangeException e ){
Console.WriteLine( e.Message );}
finally{
fout.Close();
fin.Close();
}
}
privatestaticvoid EncoderTwo(String inName,String outName){
FileStream fin =null, fout =null;try{
fin =
newFileStream( inName,FileMode.Open,FileAccess.Read );fout =
newFileStream( outName,FileMode.OpenOrCreate,FileAccess.Write );//// TODO: check the free disksapce for the output file//}
catch (FileNotFoundException e ){
Console.WriteLine( e.Message );return;}
catch (Exception e ){
Console.WriteLine( e.Message );fin.Close();
return;}
fout.SetLength( 0 );
constint binmult = 9;constint binsize = 24 * binmult;
constint binmed = 32 * binmult;
byte[] buff_in =newbyte[binsize];char[] buff_med =newchar[binmed];byte[] buff_out =newbyte[binmed];long rdlen = 0;int rtlen = 0;long totlen = fin.Length;int len;int charCount = 0;int maxCharCount = 0;try{
//Read from the input file, then decode and write to the output file.while ( rdlen < totlen ){
len = fin.Read( buff_in, 0, binsize );
// Console.WriteLine( "read: {0} bytes", len );charCount =
Convert.ToBase64CharArray( buff_in, 0, len, buff_med, 0 );if ( charCount > maxCharCount )maxCharCount = charCount;
for (int x = 0 ; x < charCount ; x++ ){
buff_out[x] =
Convert.ToByte( buff_med[x] );}
fout.Write( buff_out, 0, charCount );
rdlen += len;
rtlen += charCount;
}
Console.WriteLine("EncoderTwo: {0} bytes read and {1} bytes written", rdlen, rtlen );}
catch (FormatException e ){
Console.WriteLine( e.Message );}
finally{
fout.Close();
fin.Close();
}
}
staticvoid Main(string[] args ){
Console.WriteLine("UUEncode/UUDecode file demonstration" );Console.WriteLine("====================================" );Console.WriteLine("Enter source filename to do encode/decode tests:\n" );string i_file =Console.ReadLine();// TODO: check input file existense hereConsole.WriteLine("Encoder / Decoder 1 tests" );EncoderOne( i_file, i_file +
".enc1" );DecoderOne( i_file +
".enc1", i_file +".dec1" );Console.WriteLine("Encoder / Decoder 2 tests" );EncoderTwo( i_file, i_file +
".enc2" );DecoderTwo( i_file +
".enc2", i_file +".dec2" );Console.WriteLine("Test runs done. Press a key...\n" );Console.ReadKey();}
}
}

