1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 1.0 Special Edition- P30 potx

40 206 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Do While Not name Is Nothing Response.Write(name & "<br />") name = myfile.ReadLine() Loop myfile.Close()%> </body> </html> Here we use the File.OpenText method to open up the names.txt file. If successful, this method returns a StreamReader object that can be used to read characters (not bytes) from the fil e . Our code uses the ReadLine method, which reads all characters up to the next carriage return line feed. Although this method reads the carriage return line feeds from the stream, they are not returned as part of the return string. When the end of the file is reached, a Null string is returned. We check for this and use it to terminate our while loop. Calling the Close method closes the file. To ensure that our code remains scalable we should always close files as soon as possible. The following code shows how we can create a new text file and write a few lines to it: <%@ Page Language="VB" %><%@ Import Namespace="System.IO" %><% Dim books As StreamWriter books = File.CreateText(Server.MapPath("books.txt")) books.WriteLine("Professional ASP.NET") books.WriteLine("Professional C#") books.Close()%> Here we use the File.CreateText method to create a new file. This method returns a StreamWriter object that we can use to write data to the file. Then we call the WriteLine method of the object (which is inherited from the base class, TextWriter) and output the names of the two books. Finally, we call the Close method to close the connection to the file. Once we've written code to read or write data from a backing store (such as the file system) using the StreamReader or StreamWriter classes we can easily read and write character data from other backing stores (such as memory buffers or network connections) using the same classes. This consistency makes working with streams of data easy. The main role of the StreamReader and StreamWriter classes is essentially to convert bytes of data into characters. Different character encoding types, such as Unicode, ASCII, or UTF-8, use different byte sequences to represent their characters, but no matter where bytes are read from, or written to, these same translations are performed, so it makes sense to always use the same classes for this purpose. To support this, the classes read and write bytes of data using a Stream class, as shown in the following diagram: This generic model is very powerful. To support reading character data from different backing stores, all we require is a stream object for each backing store. Each of these stream objects inherits from the Stream class and overrides several abstract methods that can be used to read and write bytes of data; provide the current position in the stream as well as change it; determine the length of the stream; and expose the capabilities of the backing store (for example, whether it is read-only, or write-only). The following diagram shows how reading and writing from the file system, network sockets, and memory buffers is supported by this model: The FileStream, NetworkStream, and MemoryStream classes all derive from the Stream class. The StreamReader and StreamWriter classes contain a reference to the stream object they use to access the associated backing store. This reference is held in the BaseStream property (defined as type Stream). If we had a reference to a StreamReader, and we knew the backing store was actually a FileStream, we could use this property to get a reference to the original FileStream object: Dim myfile As StreamReader Dim backingStore As FileStream ' assuming backingStore and myfile are already initialized backingStore = CType(myfile.BaseStream,FileStream) backingStore.Seek(0,SeekOrigin.Begin) The capabilities of a stream object will depend on the backing data store. For example, if we're using a StreamReader to read data from a socket (for example, a web page over HTTP), we cannot change the position of the stream since we cannot push data back into a socket once it has been read. To determine the capability of a backing store the Stream class has a number of read-only properties:  CanRead- determines if data can be read from a stream. If this property returns true, the Read method can be used to read a specified number of bytes from the Stream into a byte array at a given offset, or the ReadByte method can be used to read a single byte.  CanWrite- determines if data can be written to a stream. If this property returns true, the Write method can be used to write a specified number of bytes from a byte array to the Stream, or the WriteByte method can be used to write a single byte.  CanSeek- indicates if a stream supports random access. If it does, the Position property of the stream class can be used to set the stream position. Alternatively, the Seek method can be used to set a relative position from the start of the stream, the end of the stream, or the current position of the stream. The SetLength method can also be called to change the size of the underlying backing data store object. Consider the Stream in .NET to be the replacement of the IStream interface in COM. In future versions of .NET the Stream object will automatically expose the IStream interface through COM interop. FileStream The FileStream class provides all of the functionality we would expect to have available when we are reading and writing data to files. It derives from the Stream class, so it inherits all of the properties and methods we've just discussed. The FileStream class has the following constructors that we can use to open and create files in various modes: Parameters Description path as string, mode as FileMode Specifies a path/file and how we want to work with it. FileMode is an enumeration that defines how we want to work with a file, and what actions we want to take if it already exists. We'll cover the values of FileMode shortly. path as string,mode as FileMode,access as FileAccess As for the previous constructor, but also allows us to specify if we want permissions to read, write, or read and write from the stream. Values for FileAccess are Read, ReadWrite, and Write. The default is ReadWrite. path as string,mode as FileMode,access as As with the previous constructor, but also allows us to specify what FileAccess,share as FileShare access other people will have to the file while we're working with it. Values for FileShare are None, Read, ReadWrite, Write, and Inheritable. The default is None (that is, nobody else can access the file). path as string,mode as FileMode,access as FileAccess,share as FileShare,bufferSize as Integer As with the previous constructor, but also allows us to specify the size of the internal buffer used to reduce the number of calls to the underlying operation system. The default value is 4KB. We should not change the size of this buffer unless we have good reasons to do so. path as string,mode as FileMode,access as FileAccess,share as FileShare,bufferSize as Integer,useAsync as Boolean As with the previous constructor, but also tells the class the application calling it is using asynchronous IO. This can result in better performance for large reads and writes. The default value of this parameter is False. The following code shows how we can create a new text file using the FileStream class: <%@ Page Language="VB" %><%@ Import Namespace="System.IO" %> <% Dim fs As FileStream fs = New FileStream("MyFile.Txt", FileMode.Create) fs.Close() %> Since we've specified the FileMode.Create parameter, any existing file called MyFile.Txt will be truncated (that is, all existing content will be overwritten) when the file is opened. The values of FileMode include:  Append- opens the specified file and seeks to the end of the stream. If a file does not exist it is created.  CreateNew- creates the specified file. If the file already exists, an IOException is thrown.  Create- creates the specified file, truncating the file content if it already exists.  Open- opens the specified file. If the file doesn't exist, a FileNotFound exception is thrown.  OpenToCreate- opens the specified file, and creates it if it doesn't already exist.  Truncate- opens the specified file and clears the existing contents. If the file doesn't exist, a FileNotFound exception is thrown. Once a file is opened and we have a FileStream object, we can create a reader or writer object to work with the file's contents. The following code shows how we can write a few lines of text to a file using the StreamWriter class: <%@ Page Language="VB" %><%@ Import Namespace="System.IO" %> <% Dim fs As FileStream Dim sw As StreamWriter fs = New FileStream("MyFile.Txt", FileMode.Create) sw = New StreamWriter(fs) sw.WriteLine("Professional ASP.NET") sw.WriteLine("Professional C#") sw.Close() %> When we use a writer object to write data to a stream, we should only use one writer. We should never have multiple writers per stream. Writer objects buffer data in an internal cache to reduce the number of calls to the underlying backing store and having multiple writers active on one stream will result in unpredictable results. The lifetime of the writer is tied to that of the stream. When the writer is closed, the stream is also closed by the writer, which is why we call sw.Close in this code rather than fs.Close. When a stream is closed (assuming the writer didn't close it) the writer can no longer write to the stream. The same is true for reader objects. Any attempt to perform an operation on a closed stream will result in an exception. The following code shows how we can open an existing file using the FileStream class and read lines of text from it using the StreamReader class: <%@ Page Language="VB" %><%@ Import Namespace="System.IO" %> <% Dim fs As FileStream Dim sr As StreamReader Dim line As String fs = New FileStream("MyFile.Txt", FileMode.Open) sr = New StreamReader(fs) line = sr.ReadLine() Response.Write(line & "<br />") line = sr.ReadLine() Response.Write(line & "<br />") sr.Close() %> In this code we're using the FileMode.Open parameter to tell the FileStream that we're opening an existing file. We use the ReadLine method to read two lines from the file and write them to our ASP.NET page using Response.Write. MemoryStream A memory stream allows us to read and write bytes of data from memory. It has several constructors that allow us to initialize the buffer to a given size (the default is 256 bytes), indicate whether the buffer is read-only (and can therefore not be written to), and copy a specified amount of data from an existing array. The following code demonstrates how we can use the MemoryStream class to create a byte array containing the text "Professional ASP.NET". Although something of an esoteric example, it demonstrates how we can use a stream writer to fill the memory stream with some text, and then create a byte array containing that text: <%@ Page Language="VB" %><%@ Import Namespace="System.IO" %><% Dim memstream As MemoryStream Dim writer As StreamWriter Dim array() As Byte memstream = New MemoryStream() writer = New StreamWriter(memstream) writer.Write("Professional ASP.NET") writer.Flush() array = memstream.ToArray() writer.Close()%> The StreamWriter class uses an internal 1KB buffer to write blocks of data to the underlying stream (and its associated backing store) more efficiently. Calling its Flush method causes any buffered data to be written to the underlying stream (before the 1KB limit is reached), and resets the buffer to an empty state. The Flush method is automatically called by the Close method of the StreamWriter. In our code we use the ToArray method of MemoryStream to convert the memory buffer into a byte array. We have to explicitly call the Flush method before calling this method, since the amount of data written to the stream using the Write method is less than 1KB. If we didn't call Flush first, we'd simply end up with an empty array, as no data would have actually been written to the memory stream. In this case we have to call Flush, since calling the ToArray method after calling the Close method would also result in an empty array, as the memory stream releases its resources (memory) when the Close method is called. The Capacity property can be used to determine the amount of data a memory stream can hold before it will need to reallocate its buffer. We can set this property to increase or shrink the size of the memory buffer. However, we cannot set the capacity of the memory stream to be less than the current length of the memory stream, as the length reflects how much data has already been written to the memory stream. To determine how much data is currently in a memory stream we can use the read-only Length property. The MemoryStream class automatically manages its own capacity expansion. When a memory stream is full it doubles in size, allocating a new buffer and copying the old data across. When using classes such as StreamWriter to populate a memory stream, the memory stream's Length property will not be accurate until the stream writer's Flush method is called (because of the buffering it performs). TextReader and TextWriter The StreamReader class derives from the abstract TextReader class. This class defines the base methods that are useful to applications that need to read character data. It does not define any methods for opening or connecting to an underlying data source (backing store), those are provided by derived classes such as StringReader and StreamReader. The TextReader class has the following methods: Method Name Parameters Description Close None Closes the underlying backing store connection and dispose of any held resources. Read None Reads the next character from the input stream. Read Char array, index, count Reads a specified number of characters from the input stream into an array at the specified offset. The number of characters read is returned. ReadBlock Char array, index, count Reads a specified number of characters from the input stream into an array at the specified offset. The number of characters read is returned. This method will block (that is, the method will not return) until data is available. Table continued on following page Method Name Parameters Description ReadLine None Returns a string containing the next line of characters. ReadToEnd None Reads all of the remaining content from the input stream into a string. We should not use this method for large streams, as it can consume a lot of memory. Synchronized TextReader Accepts a TextReader object as input and returns a thread-safe wrapper. This is a static method. One of the reasons the TextReader class exists is so that non-stream-oriented backing stores, such as a string, can have an interface consistent with streams. It provides a mechanism by which classes can expose or consume a text stream without having to be aware of where the underlying data stream is. For example, the following code shows how a function can output the data read from a text-oriented input stream using an ASP.NET page (written using C#): <script runat="server"> protected void WriteContentsToResponse(TextReader r) { string line; line = r.ReadLine(); while (line != null) { Response.Write(line); Response.Write("<br />"); line = r.ReadLine(); } } </script> This function is passed a TextReader, and reads lines of text using the ReadLine method. Then it writes that back to the client browser using the Response.Write method. As the HTML standard defines line breaks using the <br /> element, we write it out after each line. The StringReader class derives from TextReader in order to provide a way of accessing the contents of a string in a text-stream-oriented way. The StreamReader class extends TextReader to provide an implementation that makes it easy to read text data from a file. We could derive our own classes from TextReader to provide an implementation that makes it easy to read from our internal data source. This same model is used for the TextWriter. The StreamWriter class derives from the abstract TextWriter class. StreamWriter defines methods for writing character data. It also provides many overloaded methods for converting primitive types like bool and integer into character data: [...]... occurs), the resources held by the stream are released Under the hood the using statement causes code to be generated that calls the IDiposable.Dispose method implemented by the FileStream ASP.NET and Streams The ASP.NET page framework allows us to read and write content to a page using a stream: The Page.Response.Output property returns a TextWriter than can be used to write text content into the output... class should not be used with the FileStream or MemoryStream classes because they already buffer their own data Copying Between Streams One of the functions of the stream object not included in version 1.0 of NET is the ability to write the content of one stream into another Here is some C# code that shows how it can be implemented: public static long Pump(Stream input, Stream output) { if (input ==... the output stream of a page The Page.Request.InputStream property returns a Stream object that can be used to read bytes of data from a posted request If content, such as an XML file, was posted to an ASP.NET page, the following VB NET shows how we could read and display the data using the Page.Request.InputStream property: . string s = "a string"; long l = 0x123456789abcdef; int i = 0x12345678; char c = 'c'; float f = 1. 5f; Decimal d = 10 0.2m; bw.Write(s); bw.Write(l); . myfile.WriteLine("My name is {0} ", "Richard") myfile.WriteLine("My name is {0} {1} ", "Richard", "James") myfile.WriteLine("My name is {0} {1} {2}",. const int count = 409 6; byte[] bytes = new byte[count]; int numBytes; long totalBytes = 0; while((numBytes = input.Read(bytes, 0, count)) > 0) { output.Write(bytes, 0, numBytes); totalBytes

Ngày đăng: 03/07/2014, 07:20

Xem thêm: Professional ASP.NET 1.0 Special Edition- P30 potx

TỪ KHÓA LIÊN QUAN