C#笔记28:I/O操作

C#笔记28:I/O操作

本章概要:

1:基本文件I/O

   1.1:用于文件 I/O 的类

   1.2:用于从流读取和写入流的类

   1.3:通用 I/O 流类

2:通用I/O任务

3:独立存储 

   3.1:为什么要使用独立存储

   3.2:使用独立存储

 

     以下的区别有助于澄清文件和流的差异。文件是一些具有永久存储及特定顺序的字节组成的一个有序的、具有名称的集合。因此,关于文件,人们常会想到目录路径、磁盘存储、文件和目录名等方面。相反,流提供一种向后备存储写入字节和从后备存储读取字节的方式,后备存储可以为多种存储媒介之一。正如除磁盘外存在多种后备存储一样,除文件流之外也存在多种流。例如,还存在网络流、内存流和磁带流等。

 

1:基本文件I/O

    抽象基类 Stream 支持读取和写入字节。Stream 集成了异步支持。其默认实现根据其相应的异步方法来定义同步读取和写入,反之亦然。

    所有表示流的类都是从 Stream 类继承的。Stream 类及其派生类提供数据源和储存库的一般视图,使程序员不必了解操作系统和基础设备的具体细节。

    流涉及三个基本操作:

  • 可以从流读取。读取是从流到数据结构(如字节数组)的数据传输。

  • 可以向流写入。写入是从数据源到流的数据传输。

  • 流可以支持查找。查找是对流内的当前位置进行的查询和修改。

    根据基础数据源或储存库,流可能只支持这些功能中的一部分。例如,NetworkStreams 不支持查找。Stream 及其派生类的 CanReadCanWriteCanSeek 属性决定了不同流所支持的操作。

1.1:用于文件 I/O 的类

    Directory 提供创建、移动和枚举目录和子目录的静态方法。DirectoryInfo 类提供实例方法。

    DirectoryInfo 提供创建、移动和枚举目录和子目录的实例方法。Directory 类提供静态方法。

    DriveInfo 提供访问有关驱动器的信息的实例方法。

    File 提供用于创建、复制、删除、移动和打开文件的静态方法,并协助创建 FileStreamFileInfo 类提供实例方法。

    FileInfo 提供用于创建、复制、删除、移动和打开文件的实例方法,并协助创建 FileStreamFile 类提供静态方法。

    FileStream 支持通过其 Seek 方法随机访问文件。默认情况下,FileStream 以同步方式打开文件,但它也支持异步操作。File 包含静态方法,而 FileInfo 包含实例方法。

    FileSystemInfoFileInfoDirectoryInfo 的抽象基类。

    Path 提供以跨平台的方式处理目录字符串的方法和属性。

    DeflateStream 提供使用 Deflate 算法压缩和解压缩流的方法和属性。

    GZipStream 提供压缩和解压缩流的方法和属性。默认情况下,此类使用与 DeflateStream 类相同的算法,但可以扩展到使用其他压缩格式。

    SerialPort 提供控制串行端口文件资源的方法和属性。

     FileFileInfoDriveInfoPathDirectoryDirectoryInfo 是密封(在 Microsoft Visual Basic 中为 NotInheritable)类。可以创建这些类的新实例,但它们不能有派生类。

1.2:用于从流读取和写入流的类

    BinaryReaderBinaryWriterStreams 中读取和写入编码的字符串和基元数据类型。

    StreamReader 通过使用 Encoding 进行字符和字节的转换,从 Streams 中读取字符。StreamReader 具有一个构造函数,该构造函数根据是否存在专用于 Encodingpreamble(例如一个字节顺序标记)来尝试确定给定 Stream 的正确 Encoding 是什么。

    StreamWriter 通过使用 Encoding 将字符转换为字节,向 Streams 写入字符。

    StringReaderStrings 中读取字符。StringReader 允许您用相同的 API 来处理 Strings,因此您的输出可以是 String 或以任何编码表示的 Stream

    StringWriterStrings 写入字符。StringWriter 允许您用相同的 API 来处理 Strings,因此您的输出可以是 String 或以任何编码表示的 Stream

    TextReaderStreamReaderStringReader 的抽象基类。抽象 Stream 类的实现用于字节输入和输出,而 TextReader 的实现用于 Unicode 字符输出。

    TextWriterStreamWriterStringWriter 的抽象基类。抽象 Stream 类的实现用于字节输入和输出,而 TextWriter 的实现用于 Unicode 字符输出。

1.3:通用 I/O 流类

    BufferedStream 是向另一个 Stream(例如 NetworkStream)添加缓冲的 Stream。(FileStream 内部已具有缓冲,MemoryStream 不需要缓冲。)BufferedStream 可以围绕某些类型的流来构成以提高读写性能。缓冲区是内存中的字节块,用于缓存数据,从而减少对操作系统的调用次数。

    CryptoStream 将数据流链接到加密转换。虽然 CryptoStream 是从 Stream 派生的,但它不属于 System.IO 命名空间,而是在 System.Security.Cryptography 命名空间中。

    MemoryStream 是一个非缓冲的流,可以在内存中直接访问它的封装数据。该流没有后备存储,可用作临时缓冲区。

NetworkStream 表示网络连接上的 Stream。虽然 NetworkStream 是从 Stream 派生的,但它不属于 System.IO 命名空间,而是在 System.Net.Sockets 命名空间中。

 

2:通用I/O任务

     System.IO 命名空间提供若干个类,通过这些类可以对文件、目录和流执行各种操作(如读取和写入)。

     地址:http://msdn.microsoft.com/zh-cn/library/ms404278.aspx

 

3:独立存储

     独立存储是一种数据存储机制,它在代码与保存的数据之间定义了标准化的关联方式,从而提供隔离性和安全性。同时,标准化也提供了其他好处。管理员可以使用旨在操作独立存储的工具来配置文件存储空间、设置安全策略及删除未使用的数据。通过独立存储,代码不再需要使用唯一的路径来指定文件系统中的安全位置,同时可以保护数据免遭只具有独立存储访问权限的其他应用程序的损坏。不再需要指示应用程序的存储区域位置的硬编码信息。

3.1:为什么要使用独立存储

     独立存储可用于许多情况。以下介绍了几种最典型的情况:

  • 下载的控件。不允许从 Internet 下载的托管代码控件通过正常的 I/O 类写入硬盘,但它们可以使用独立存储来持久保存用户设置和应用程序状态。

  • 共享组件存储。应用程序间共享的组件可以使用独立存储来提供对数据存储区的有控制的访问。

  • 服务器存储。服务器应用程序可以使用独立存储为请求应用程序的大量用户提供单独的存储区。因为独立存储始终按用户进行隔离,所以服务器必须模拟发出请求的用户。在这种情况下,根据主体的标识隔离数据,该标识与应用程序用来区分其用户的标识是同一个标识。

  • 漫游。应用程序还可以将独立存储和漫游用户配置文件一起使用。这允许用户的独立存储区和配置文件一起漫游。

     虽然独立存储非常适合于以上所述的情况,但在少数情况下,您“不”应该使用独立存储:

  • 不要使用独立存储来存储重要机密(例如不加密的密钥或密码),因为独立存储对高度受信任的代码、非托管代码或计算机的受信任用户不设防。

  • 不要使用独立存储来存储代码。

  • 不要使用独立存储来存储配置和部署设置,它们是由管理员来控制的。(因为管理员不控制用户首选项,所以用户首选项不被认为是配置设置。)

     当今的许多应用程序都使用数据库来存储和隔离数据,在这种情况下,数据库中的一个或多个行可能代表某个特定用户的存储。当用户数较少时、当使用数据库的系统开销非常大时或当不存在数据库功能时,您可以选择使用独立存储而不使用数据库。另外,当应用程序要求比数据库的行所提供的存储更加灵活和复杂的存储时,独立存储也可以提供一个可行的替代方案。

3.2:使用独立存储

     本文不再展开独立存储议题,更多内容,参看:

     http://msdn.microsoft.com/zh-cn/library/3ak841sy.aspx

 

练习:

1.You need to return the contents of an isolated storage file as a string.  The file is machine-scoped and is named 
Settings.dat. Which code segment should you use? 
A. IsolatedStorageFileStream isoStream; 
isoStream = new IsolatedStorageFileStream("Settings.dat", FileMode.Open);   
string result = new StreamReader(isoStream).ReadToEnd();
B. IsolatedStorageFile isoFile;isoFile = IsolatedStorageFile.GetMachineStoreForAssembly(); 
IsolatedStorageFileStream isoStream;
isoStream = new IsolatedStorageFileStream("Settings.dat", FileMode.Open, isoFile);  
string result = new StreamReader(isoStream).ReadToEnd();
C. IsolatedStorageFileStream isoStream; 
isoStream=new IsolatedStorageFileStream("Settings.dat", FileMode.Open);
string result = isoStream.ToString(); 
D. IsolatedStorageFile isoFile;
isoFile = IsolatedStorageFile.GetMachineStoreForAssembly(); 
IsolatedStorageFileStream isoStream;
isoStream = new IsolatedStorageFileStream("Settings.dat", FileMode.Open, isoFile);  
string result = isoStream.ToString(); 
Answer: B

 

2.You are writing an application that uses isolated storage to store user preferences. The application uses multiple 
assemblies. Multiple users will use this application on the same computer. You need to create a directory named           
Preferences in the isolated storage area that is scoped to the current Microsoft Windows identity and assembly.   
Which code segment should you use? 
A. IsolatedStorageFile store;store = IsolatedStorageFile.GetUserStoreForAssembly();
store.CreateDirectory("Preferences");
B. IsolatedStorageFile store; 
store = IsolatedStorageFile.GetMachineStoreForAssembly();
store.CreateDirectory("Preferences");
C. IsolatedStorageFile store; 
store = IsolatedStorageFile.GetUserStoreForDomain();
store.CreateDirectory("Preferences");
D. IsolatedStorageFile store; 
store = IsolatedStorageFile.GetMachineStoreForApplication();
store.CreateDirectory("Preferences");
Answer: A

 

3.You need to write a code segment that transfers the first 80 bytes from a stream variable named stream1 into a 
new byte array named byteArray. You also need to ensure that the code segment assigns the number of bytes that   
are transferred to an integer variable named bytesTransferred. Which code segment should you use? 
A. bytesTransferred = stream1.Read(byteArray, 0, 80);
B. for (int i = 0; i < 80; i++)   
{  stream1.WriteByte(byteArray[i]);  
bytesTransferred = i;    
if (!stream1.CanWrite)   

{     break;  }}
C. while (bytesTransferred < 80)  
{  stream1.Seek(1, SeekOrigin.Current);    
byteArray[bytesTransferred++] =    Convert.ToByte(stream1.ReadByte());}
D. stream1.Write(byteArray, 0, 80);
bytesTransferred = byteArray.Length;
Answer: A

 

4.You are writing a method that accepts a string parameter named message.   Your method must break the
message parameter into individual lines of text and pass each line to a second method named Process.   Which 
code segment should you use? 
A. StringReader reader = new StringReader(message);
Process(reader.ReadToEnd());
reader.Close();
B. StringReader reader = new StringReader(message);
while (reader.Peek() != -1) {    string line = reader.Read().ToString();   
Process(line);}
reader.Close();
C. StringReader reader = new StringReader(message);
Process(reader.ToString());
reader.Close();
D. StringReader reader = new StringReader(message);
while (reader.Peek() != -1) {    Process(reader.ReadLine());}
reader.Close();
Answer: D

 

5.You are writing a method to compress an array of bytes. The bytes to be compressed are passed to the method 
in a parameter named document.    You need to compress the contents of the incoming parameter.    Which code 
segment should you use? 
A. MemoryStream inStream = new MemoryStream(document);     
GZipStream zipStream = new GZipStream(inStream, CompressionMode.Compress);  
byte[] result = new byte[document.Length];
zipStream.Write(result, 0, result.Length); 
return result;
B. MemoryStream stream = new MemoryStream(document);

GZipStream zipStream = new GZipStream(stream, CompressionMode.Compress);
zipStream.Write(document, 0, document.Length);
zipStream.Close();
return stream.ToArray();
C. MemoryStream outStream = new MemoryStream();
GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress);
zipStream.Write(document, 0, document.Length);
zipStream.Close();
return outStream.ToArray(); 
D. MemoryStream inStream = new MemoryStream(document);     
GZipStream zipStream = new GZipStream(inStream, CompressionMode.Compress);  
MemoryStream outStream = new MemoryStream(); 
int b;
while ((b = zipStream.ReadByte()) != -1)
{  outStream.WriteByte((byte)b);}  
return outStream.ToArray(); 
Answer: C

 

6.You need to write a code segment that transfers the contents of a byte array named dataToSend by using a 
NetworkStream object named netStream. You need to use a cache of size 8,192 bytes. Which code segment should 
you use? 

TestInside    70-536
A. MemoryStream memStream = new MemoryStream(8192);   
memStream.Write(dataToSend, 0, (int) netStream.Length);
B. MemoryStream memStream = new MemoryStream(8192); 
netStream.Write(dataToSend, 0, (int) memStream.Length);
C. BufferedStream bufStream = new BufferedStream(netStream, 8192);     
bufStream.Write(dataToSend, 0, dataToSend.Length);
D. BufferedStream bufStream = new BufferedStream(netStream);      
bufStream.Write(dataToSend, 0, 8192);
Answer: C

 

7.You need to read the entire contents of a file named Message.txt into a single string variable.    Which code
segment should you use? 
A. string result = null;
StreamReader reader = new StreamReader("Message.txt"); 
result = reader.Read().ToString();
B. string result = null;
StreamReader reader = new StreamReader("Message.txt"); 
result = reader.ReadToEnd();
C. string result = string.Empty;
StreamReader reader = new StreamReader("Message.txt");   
while (!reader.EndOfStream) {    result += reader.ToString();}
D. string result = null;
StreamReader reader = new StreamReader("Message.txt");   
result = reader.ReadLine();
Answer: B

 

8.You are writing a method to compress an array of bytes. The array is passed to the method in a parameter 
named document. You need to compress the incoming array of bytes and return the result as an array of bytes. 
Which code segment should you use? 
A. MemoryStream strm = new MemoryStream(document);
DeflateStream deflate = new DeflateStream(strm, CompressionMode.Compress);  

byte[] result = new byte[document.Length];deflate.Write(result, 0, result.Length);   
return result;
B. MemoryStream strm = new MemoryStream(document);
DeflateStream deflate = new DeflateStream(strm, CompressionMode.Compress);
deflate.Write(document, 0, document.Length); 
deflate.Close();
return strm.ToArray(); C. MemoryStream strm = new MemoryStream();
DeflateStream deflate = new DeflateStream(strm, CompressionMode.Compress);
deflate.Write(document, 0, document.Length); 
deflate.Close();
return strm.ToArray();
D. MemoryStream inStream = new MemoryStream(document);     
DeflateStream deflate = new DeflateStream(inStream, CompressionMode.Compress);     
MemoryStream outStream = new MemoryStream(); 
int b;
while ((b = deflate.ReadByte()) != -1)  
{outStream.WriteByte((byte)b);}
return outStream.ToArray(); 
Answer: C

C#笔记28:I/O操作本文基于Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
上一篇:T-SQL笔记7:临时表和表变量


下一篇:T-SQL笔记8:索引