FileStream
object, you can actually assign the returning type to a Stream
object because the FileStream
object inherits from the Stream
object.
To copy the content of one file into another, you use the Read()
method from the Stream
class and read the content from the file into an byte array. Read()
returns the number of bytes read from the stream (in this case the file) and returns 0 if there are no more bytes to read. The Write()
method of the Stream
class writes the data stored in the byte array into the stream (which in this case is another file). Finally, you close both the Stream
objects.
In addition to the Read()
and Write()
methods, the Stream
object supports the following methods:
□ ReadByte()
— Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream
□ WriteByte()
— Writes a byte to the current position in the stream and advances the position within the stream by 1 byte
□ Seek()
— Sets the position within the current stream
The following example writes some text to a text file, closes the file, reopens the file, seeks to the fourth position in the file, and reads the next six bytes:
try {
const int BUFFER_SIZE = 8192;
string text = 'The Stream class is defined in the System.IO namespace.';
byte[] data = ASCIIEncoding.ASCII.GetBytes(text);
byte[] buffer = new byte[BUFFER_SIZE];
string filePath = @'C: emp extfile.txt';
//---writes some text to file---
Stream s_out = File.OpenWrite(filePath);
s_out.Write(data, 0, data.Length);
s_out.Close();
//---opens the file for reading---
Stream s_in = File.OpenRead(filePath);
//---seek to the fourth position---
s_in.Seek(4, SeekOrigin.Begin);
//---read the next 6 bytes---
int bytesRead = s_in.Read(buffer, 0, 6);
Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead));
s_in.Close();
s_out.Close();
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
BufferedStream
To improve its performance, the BufferedStream
class works with another Stream
object. For instance, the previous example used a buffer size of 8192 bytes when reading from a text file. However, that size might not be the ideal size to yield the optimum performance from your computer. You can use the BufferedStream
class to let the operating system determine the optimum buffer size for you. While you can still specify the buffer size to fill up your buffer when reading data, your buffer will now be filled by the BufferedStream
class instead of directly from the stream (which in the example is from a file). The BufferedStream
class fills up its internal memory store in the size that it determines is the most efficient.
The BufferedStream
class is ideal when you are manipulating large streams. The following shows how the previous example can be speeded up using the BufferedStream
class:
try {
const int BUFFER_SIZE = 8192;
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
string filePath = @'C: empVS2008Pro.png';
string filePath_backup = @'C: empVS2008Pro_bak.png';
Stream s_in = File.OpenRead(filePath);
Stream s_out = File.OpenWrite(filePath_backup);
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
You use a BufferedStream
object over a Stream
object, and all the reading and writing is then done via the BufferedStream
objects.
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: empVS2008Pro.png';
string filePath_backup = @'C: empVS2008Pro_bak.png';