C# Files & Streams

advertisement
Prolog:
Try this before we proceed:
using System;
// Program start class
class InteractiveWelcome
{
// Main begins program execution.
public static void Main()
{
// Write to console/get input
Console.Write("What is your name?: ");
Console.Write("Salam, {0}! ", Console.ReadLine());
Console.WriteLine("Welcome to the E-Commerce Course !");
Console.ReadLine();
}
}
Files and File Streams in C#
C# provides a number stream classes that may be used for various I/O purposes. The
stream classes form what is known as streams-based I/O framework. All stream classed are
based on the Stream abstract base classes. The FileStream is one example of stream
classes.
Stream Classes
The .NET Framework classes offer a stream-based I/O framework, with the core classes in
the System.IO namespace. All classes that represent streams inherit from the Stream class,
and the key classes are listed in Table 1.
Class
Description
Stream
The abstract base class Stream supports reading and
writing bytes.
FileStream
In addition to basic Stream behavior, this class
supports random access to files through its Seek
method and supports both synchronous and
asynchronous operations.
MemoryStream
A nonbuffered stream whose encapsulated data is
directly accessible in memory. This stream has no
backing store and might be useful as a temporary
buffer.
BufferedStream
A Stream that adds buffering to another Stream, such
as a NetworkStream. (FileStream already has
buffering internally, and a MemoryStream doesn't
need buffering.) A BufferedStream object can be
composed around some types of streams to improve
read and write performance.
TextReader
The abstract base class for StreamReader and
StringReader objects. While the implementations of
the abstract Stream class are designed for byte input
and output, the implementations of TextReader are
StreamReader
StringReader
TextWriter
StreamWriter
StringWriter
BinaryReader
BinaryWriter
designed for Unicode character output.
Reads characters from a Stream, using Encoding to
convert characters to and from bytes.
Reads characters from a String. StringReader allows
you to treat a String with the same API; thus, your
output can be either a Stream in any encoding or a
String.
The abstract base class for StreamWriter and
StringWriter objects. While the implementations of the
abstract Stream class are designed for byte input and
output, the implementations of TextWriter are
designed for Unicode character input.
Writes characters to a Stream, using Encoding to
convert characters to bytes.
Writes characters to a String. StringWriter allows you
to treat a String with the same API; thus, your output
can be either a Stream in any encoding or a String.
Reads binary data from a stream.
Writes binary data to a stream.
The design of the Stream class and its derivatives is intended to provide a generic view of
data sources and destinations so that the developer can interchangeably use any of these
classes without redesigning the application. In general, Stream objects are capable of one
or more of the following:



Reading and transfer of data from a stream into a data structure, such as an array of
bytes
Writing and transfer of data from a data structure into a stream
Seeking: querying and modifying of the current position within a stream
Note that a given stream might not support all these features. For example, NetworkStream
objects don't support seeking. You can use the CanRead, CanWrite, and CanSeek properties
of Stream and its derived classes to determine precisely which operations a given stream
does in fact support.
Example 1 : FileStreams:
FileStreams are used to work with raw byte data:
using System.IO;
public class StreamsIOApp
{
public static void Main(string[] args)
{
byte[] buf1 = new Byte[]
{76,101,116,32,116,104,101,114,101,
32,98,101,32,108,105,103,104,116};
Stream s = new FileStream("Example1.txt", FileMode.Create);
s.Write(buf1, 0, buf1.Length);
s.Close();
s = new FileStream("Example1.txt", FileMode.Open);
int i;
string str = "";
if (s.CanRead)
{
for (i = 0; (i = s.ReadByte()) != -1; i++)
{
str += (char)i;
}
}
s.Close();
Console.WriteLine(str);
}
}
Example 2:
The use of Seek Operations:
byte[] buf2 = new Byte[]
{97,112,112,108,101,115,97,117,99,101};
s = new FileStream("Example1.txt", FileMode.Open);
Console.WriteLine("Length: {0}, Position: {1}", s.Length, s.Position);
if (s.CanSeek)
{
s.Seek(13, SeekOrigin.Begin);
Console.WriteLine("Position: {0}", s.Position);
s.Write(buf2, 0, buf2.Length);
}
str = "";
s.Seek(0, SeekOrigin.Begin);
for (i = 0; (i = s.ReadByte()) != -1; i++)
{
str += (char)i;
}
Console.WriteLine(str);
The Use of SetLength:
str = "";
s.SetLength(s.Length - 4);
s.Seek(0, SeekOrigin.Begin);
for (i = 0; (i = s.ReadByte()) != -1; i++)
{
str += (char)i;
}
s.Close();
Console.WriteLine(str);
Appending
byte[] buf4 = new Byte[]
{32,97,110,100,32,112,101,97,114,115};
s = new FileStream("Example1.txt", FileMode.Append, FileAccess.Write);
s.Write(buf4, 0, buf4.Length);
s.Close();
s = new FileStream("Foo.txt", FileMode.Open);
str = "";
for (i = 0; (i = s.ReadByte()) != -1; i++)
{
str += (char)i;
}
Console.WriteLine(str);
s.Close();
StreamWriter and StreamReader:
To work with text, we use the intermediate classes: StreamWriter and StreamReader:
public class ReadWriteApp
{
public static void Main(string[] args)
{
FileStream s = new FileStream("Bar.txt", FileMode.Create);
StreamWriter w = new StreamWriter(s);
w.Write("Hello World");
w.Close();
s = new FileStream("Bar.txt", FileMode.Open);
StreamReader r = new StreamReader(s);
string t;
while ((t = r.ReadLine()) != null)
{
Console.WriteLine(t);
}
w.Close();
}
}
Paths in C#
Because C# treats the backslash the same way as C and C++ do, if you want to specify a
path for a file, you have three choices. You can either use double backslashes, as in:
s = new FileStream("C:\\temp\\Goo.txt", FileMode.Create);
...or use forward (Unix-style) slashes:
s = new FileStream("C:/temp/Goo.txt", FileMode.Create);
...or use the "@" character, which is a control-character suppressor:
s = new FileStream(@"C:\temp\Goo.txt", FileMode.Create);
Memory and Buffered Streams
The classes MemoryStream and BufferedStream are both derived from the abstract Stream
class, just as FileStream is. Therefore, MemoryStream and BufferedStream share many of
the same characteristics and functionality. Both are designed for streaming data into and
out of memory rather than persistent storage. Both can be associated with a stream of
another kind.such as a file.if required, and thus both can be used to act as a buffer between
memory and persistent storage. The MemoryStream class offers methods such as WriteTo,
which will write to another stream. Similarly, a BufferedStream object is normally
associated with another stream on construction, and when you close the BufferedStream, its
contents are flushed to the associated stream. In the following example, we first create a
MemoryStream object with an initial capacity of 64 bytes and print some arbitrary property
values. Then we write out 64 bytes and report the same properties. We then use
MemoryStream.GetBuffer to get a byte array of the entire contents of the stream and print
the values, before finally closing the stream:
class MemStreamApp
{
static void Main(string[] args)
{
MemoryStream m = new MemoryStream(64);
Console.WriteLine("Length: {0}\tPosition: {1}\tCapacity: {2}",
m.Length, m.Position, m.Capacity);
for (int i = 0; i < 64; i++)
{
m.WriteByte((byte)i);
}
Console.WriteLine("Length: {0}\tPosition: {1}\tCapacity: {2}",
m.Length, m.Position, m.Capacity);
Console.WriteLine("\nContents:");
byte[] ba = m.GetBuffer();
foreach (byte b in ba)
{
Console.Write("{0,-3}", b);
}
m.Close();
}
}
class BufStreamApp
{
static void Main(string[] args)
{
// Create a FileStream for the BufferedStream.
FileStream fs = new FileStream("Hoo.txt",
FileMode.Create, FileAccess.ReadWrite);
BufferedStream bs = new BufferedStream(fs);
Console.WriteLine("Length: {0}\tPosition: {1}",
bs.Length, bs.Position);
for (int i = 0; i < 64; i++)
{
bs.WriteByte((byte)i);
}
Console.WriteLine("Length: {0}\tPosition: {1}",
bs.Length, bs.Position);
// Reset to the beginning and read the data.
Console.WriteLine("\nContents:");
byte[] ba = new byte[bs.Length];
bs.Position = 0;
bs.Read(ba, 0, (int)bs.Length);
foreach (byte b in ba)
{
Console.Write("{0,-3}", b);
}
// Write some more, exceeding capacity.
string s = "Foo";
for (int i = 0; i < 3; i++)
{
bs.WriteByte((byte)s[i]);
}
Console.WriteLine("\nLength: {0}\tPosition: {1}\t",
bs.Length, bs.Position);
for (int i = 0; i < (256-67)+1; i++)
{
bs.WriteByte((byte)i);
}
Console.WriteLine("\nLength: {0}\tPosition: {1}\t",
bs.Length, bs.Position);
bs.Close();
}
}
String Writer:
class StringReadWriteApp
{
static void Main(string[] args)
{
StringWriter w = new StringWriter();
w.WriteLine("Write a Sentence of {0} Chars", 60);
string s = "A pocket full of Riyals";
w.Write(s);
w.Write(w.NewLine);
w.Write(String.Format(4 +" and " +20 +" blackbirds"));
w.Write(new StringBuilder(" baked in a pie"));
w.WriteLine();
w.Close();
Console.WriteLine(w);
}
}
Console.WriteLine();
StringReader r = new StringReader(w.ToString());
string t = r.ReadLine();
Console.WriteLine(t);
Console.Write((char)r.Read());
char[] ca = new char[37];
r.Read(ca, 0, 19);
Console.Write(ca);
r.ReadBlock(ca, 0, 37);
Console.Write(ca);
Console.WriteLine(r.ReadToEnd());
r.Close();
w.Close();
Binary Readers and Writers
Recall that the StreamWriter class provides a text-interpolation layer on top of another
stream, such as a FileStream. The StreamWriter.Write method is heavily overloaded. Thus,
not only can we pass it text, we also can pass it data of type char, int, float, or any other
standard type.as well as an open-ended (params) number of objects and anything derived
from those objects. Of course, this works similarly to the way that Console.Write works: all
data of all types is converted to text before being written to the stream. The BinaryWriter
class allows you to write data to a stream without this text interpolation so that the data is
written in binary form. For example, compare the two files that result from the following
code.one written by using StreamWriter, the other with BinaryWriter:
class BinReadWriteApp
{
static void Main(string[] args)
{
Stream s = new FileStream("xxx.txt", FileMode.Create);
StreamWriter w = new StreamWriter(s);
w.Write("Hello World ");
w.Write(123);
w.Write(' ');
w.Write(45.67);
w.Close();
s.Close();
Stream t = new FileStream("yyy.dat", FileMode.Create);
BinaryWriter b = new BinaryWriter(t);
b.Write("Hello World ");
b.Write(123);
b.Write(' ');
b.Write(45.67);
b.Close();
t.Close();
}
}
Download