: C# 2008 Programmer

The FileStream Class

The FileStream Class

The FileStream class is designed to work with files, and it supports both synchronous and asynchronous read and write operations. Earlier, you saw the use of the Stream object to read and write to file. Here is the same example using the FileStream class:

try {
const int BUFFER_SIZE = 8192;
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
string filePath = @"C:tempVS2008Pro.png";
string filePath_backup = @"C:tempVS2008Pro_bak.png";
FileStream fs_in = File.OpenRead(filePath);
FileStream fs_out = File.OpenWrite(filePath_backup);
while ((bytesRead = fs_in.Read(buffer, 0, BUFFER_SIZE)) > 0) {
fs_out.Write(buffer, 0, bytesRead);
}
fs_in.Dispose();
fs_out.Dispose();
fs_in.Close();
fs_out.Close();
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
}

If the size of the file is large, this program will take a long time because it uses the blocking Read() method. A better approach would be to use the asynchronous read methods BeginRead() and EndRead().

BeginRead() starts an asynchronous read from a FileStream object. Every BeginRead() method called must be paired with the EndRead() method, which waits for the pending asynchronous read operation to complete. To read from the stream synchronously, you call the BeginRead() method as usual by providing it with the buffer to read, the offset to begin reading, size of buffer, and a call back delegate to invoke when the read operation is completed. You can also provide a custom object to distinguish different asynchronous operations (for simplicity you just pass in null here):

IAsyncResult result =
fs_in.BeginRead(buffer, 0, BUFFER_SIZE, new AsyncCallback(readCompleted), null);

The following program shows how you can copy the content of a file into another asynchronously:

class Program {
static FileStream fs_in;
static FileStream fs_out;
const int BUFFER_SIZE = 8192;
static byte[] buffer = new byte[BUFFER_SIZE];
static void Main(string[] args) {
try {
string filePath = @"C:tempVS2008Pro.png";
string filePath_backup = @"C:tempVS2008Pro_bak.png";
//---open the files for reading and writing---
fs_in = File.OpenRead(filePath);
fs_out = File.OpenWrite(filePath_backup);
Console.WriteLine("Copying file...");
//---begin to read asynchronously---
IAsyncResult result =
fs_in.BeginRead(buffer, 0, BUFFER_SIZE,
new AsyncCallback(readCompleted), null);
//---continue with the execution---
for (int i = 0; i < 100; i++) {
Console.WriteLine("Continuing with the execution...{0}", i);
System.Threading.Thread.Sleep(250);
}
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
//---when a block of data is read---
static void readCompleted(IAsyncResult result) {
//---simulate slow reading---
System.Threading.Thread.Sleep(500);
//---reads the data---
int bytesRead = fs_in.EndRead(result);
//---writes to another file---
fs_out.Write(buffer, 0, bytesRead);
if (bytesRead > 0) {
//---continue reading---
result =
fs_in.BeginRead(buffer, 0, BUFFER_SIZE,
new AsyncCallback(readCompleted), null);
} else {
//---reading is done!---
fs_in.Dispose();
fs_out.Dispose();
fs_in.Close();
fs_out.Close();
Console.WriteLine("File copy done!");
}
}
}

Because the reading may happen so fast for a small file, you can insert Sleep() statements to simulate reading a large file. Figure11-3 shows the output.


Figure 11-3


: 1.068. /Cache: 3 / 0