} 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: empVS2008Pro.png';
string filePath_backup = @'C: empVS2008Pro_bak.png';
//---open the files for reading and writing---
fs_in = File.OpenRead(filePath);
fs_out = File.OpenWrite(filePath_backup);
Console.WriteLine('Copying file...');
//---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();
}
}
Because the reading may happen so fast for a small file, you can insert Sleep()
statements to simulate reading a large file. Figure 11-3 shows the output.

Figure 11-3
MemoryStream
Sometimes you need to manipulate data in memory without resorting to saving it in a file. A good example is the PictureBox
control in a Windows Form. For instance, you have a picture displayed in the PictureBox
control and want to send the picture to a remote server, say a Web Service. The PictureBox
control has a Save()
method that enables you to save the image to a Stream
object.
Instead of saving the image to a FileStream
object and then reloading the data from the file into a byte array, a much better way would be to use a MemoryStream
object, which uses the memory as a backing store (which is more efficient compared to performing file I/O; file I/O is relatively slower).
The following code shows how the image in the PictureBox
control is saved into a MemoryStream
object:
//---create a MemoryStream object---
MemoryStream ms1 = new MemoryStream();
//---save the image into a MemoryStream object---
pictureBox1.Image.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
To extract the image stored in the MemoryStream
object and save it to a byte array, use the Read()
method of the MemoryStream
object:
//---read the data in ms1 and write to buffer---
ms1.Position = 0;
byte[] buffer = new byte[ms1.Length];
int bytesRead = ms1.Read(buffer, 0, (int)ms1.Length);
With the data in the byte array, you can now proceed to send the data to the Web Service. To verify that the data stored in the byte array is really the image in the PictureBox
control, you can load it back