本文摘自微软的MSDN。
以我个人的编程经历,在解决问题时的第一反映就是——到baidu或是google搜一下,而身边的人也是这么对我说的,无论是同事还是头,虽然也有人说微软的 MSDN 是个好东西,我自己也知道,但对于一个没有多少项目经验的人来说,使用MSDN的确有些困难,因为你不知道如何在MSDN 中找到解决问题的办法,换句话说,MSDN 不会直接告诉你,你的问题应该如何解决。
但 MSDN 对于一个求知欲强,善于思考的人来说,是不可或缺的。网上的东西永远只是事物的一个侧面,而 MSDN 却是知识的一个体系。我希望你能明白我的意思:这就好像信息和知识的区别。信息只有经过自己汇总,比较,反思,无数次的假设,无数次的否定自己,才能成为知识,自己的东西。凡事都有第一次,我最初使用 MSDN 也是出于无奈,因为涉密,客户不允许上网,所以碰到问题时,我根本无法及时解决,在这样的背景下,我开始使用 MSDN,通过它的链接,你可以学习到相关的所有知识,加深对问题的理解。
下面就要开始我说的内容,为了保持文章的原意,我会贴出英文,并在后边给出这段英文的大概意思,以避免歧义,和对表述的差异。
The abstract base class Stream supports reading and writing bytes. Stream integrates asynchronous support. Its default implementations define synchronous reads and writes in terms of their corresponding asynchronous methods, and vice versa. (大意:Stream类是一个抽象类,它支持读写字节的操作。)
All classes that represent streams inherit from the Stream class. The Stream class and its derived classes provide a generic view of data sources and repositories, isolating the programmer from the specific details of the operating system and underlying devices. (大意:所有关于流的类都是从Stream类继承的。Stream类及其子类提供了数据源和存储的通用视图,使得程序可以独立于操作系统和底层设备的细节。)
Streams involve these fundamental operations (大意:流涉及的一些基本操作):
1. Streams can be read from. Reading is the transfer of data from a stream into a data structure, such as an array of bytes.
2. Streams can be written to. Writing is the transfer of data from a data source into a stream.
3. Streams can support seeking. Seeking is the querying and modifying of the current position within a stream.
Depending on the underlying data source or repository, streams might support only some of these capabilities. For example, NetworkStreams do not support seeking. The CanRead, CanWrite, and CanSeek properties of Stream and its derived classes determine the operations that various streams support.(大意:可以从流中读取数据,可以向流中写入数据,流也支持定位(Seeking)。读是将流中的数据读到一个数据结构中,如字节数组。写是将数据写入到流中。而定位(Seeking)则是在流中查询和修改当前的位置。当然网络流(NetworkStreams )不支持定位(Seeking),这是显而易见的。)
Classes Used for File I/O (大意:用于文件IO的类):
1. Directory provides static methods for creating, moving, and enumerating through directories and subdirectories. The DirectoryInfo class provides instance methods.( 大意: Directory 类提供创建,移动,遍历目录和子目录的静态方法。)2. DirectoryInfo provides instance methods for creating, moving, and enumerating through directories and subdirectories. The Directory class provides static methods. (大意:DirectoryInfo类提供创建,移动遍历目录和子目录的实例方法。)
3. DriveInfo provides instance methods for accessing information about a drive. (大意:DriveInfo 类提供访问驱动器信息的实例方法。)
4. File provides static methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of a FileStream. The FileInfo class provides instance methods. (大意:File 类提供创建,复制,删除,移动,打开文件的静态方法,并且帮助创建FileStream对象。)
5. FileInfo provides instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of a FileStream. The File class provides static methods. (大意:FileInfo 类提供提供创建,复制,删除,移动,打开文件的实例方法。)
6. FileStream supports random access to files through its Seek method. FileStream opens files synchronously by default, but supports asynchronous operation as well. File contains static methods, and FileInfo contains instance methods. (大意:FileStream 类通过Seek方法,支持随机访问文件。)
7. FileSystemInfo is the abstract base class for FileInfo and DirectoryInfo. (大意:FileSystemInfo 是抽象类,类 FileInfo 和DirectoryInfo继承该类。)
8. Path provides methods and properties for processing directory strings in a cross-platform manner. (大意:Path 类以跨平台的方式处理目录字符串。)
9. DeflateStream provides methods and properties for compressing and decompressing streams using the Deflate algorithm. (大意:DeflateStream 类使用 Deflate 算法压缩和解压流。)
10. GZipStream provides methods and properties for compressing and decompressing streams. By default, this class uses the same algorithm as the DeflateStream class, but can be extended to use other compression formats. (大意:GZipStream 类也是压缩和解压流。默认情况下,和DeflateStream 一样,但是可以扩展使用其他算法。)
11. SerialPort provides methods and properties for controlling a serial port file resource. (大意:SerialPort 类控制串行端口资源。)
File, FileInfo, DriveInfo, Path, Directory, and DirectoryInfo are sealed (in Microsoft Visual Basic, NotInheritable) classes. You can create new instances of these classes, but they cannot have derived classes. (大意:类File, FileInfo, DriveInfo, Path, Directory, and DirectoryInfo 都是密封类,不被其他类再继承。)
Classes Used for Reading from and Writing to Streams (大意:用来读取流的类):
1. BinaryReader and BinaryWriter read and write encoded strings and primitive data types from and to Streams. (大意:类BinaryReader and BinaryWriter 处理编码的字符串和基础数据类型。)2. StreamReader reads characters from Streams, using Encoding to convert characters to and from bytes. StreamReader has a constructor that attempts to ascertain what the correct Encoding for a given Stream is, based on the presence of an Encoding-specific preamble, such as a byte order mark.
3. StreamWriter writes characters to Streams, using Encoding to convert characters to bytes. (大意:StreamReader 类和 StreamWriter 类使用你指定的编码从流中读取字符或将字符写入到流中。)
4. StringReader reads characters from Strings. StringReader allows you to treat Strings with the same API, so your output can be either a Stream in any encoding or a String.
5. StringWriter writes characters to Strings. StringWriter allows you to treat Strings with the same API, so your output can be either a Stream in any encoding or a String. (大意:StringReader 类和 StringWriter 类从字符串读取字符或将字符写入字符串。)
6. TextReader is the abstract base class for StreamReader and StringReader. While the implementations of the abstract Stream class are designed for byte input and output, the implementations of TextReader are designed for Unicode character output.
7. TextWriter is the abstract base class for StreamWriter and StringWriter. 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. (大意:TextReader 类和 TextWriter 类都是抽象类。)
Common I/O Stream Classes (大意:通用IO流类):
1. A BufferedStream is a Stream that adds buffering to another Stream such as a NetworkStream. (FileStream already has buffering internally, and a MemoryStream does not need buffering.) A BufferedStream can be composed around some types of streams in order to improve read and write performance. A buffer is a block of bytes in memory used to cache data, thereby reducing the number of calls to the operating system. (大意:BufferedStream 类将缓冲区添加到另一个流中,比如网络流。)2. A CryptoStream links data streams to cryptographic transformations. Although CryptoStream derives from Stream, it is not part of the System.IO namespace, but is in the System.Security.Cryptography namespace. (大意:CryptoStream 类定义将数据流链接到加密转换的流。)
3. A MemoryStream is 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. (大意:MemoryStream 类不是一个被缓存的流,它封装的数据直接访问内存。)
4. A NetworkStream represents a Stream over a network connection. Although NetworkStream derives from Stream, it is not part of the System.IO namespace, but is in the System.Net.Sockets namespace. (大意:NetworkStream 类表示为网络连接的流。)
I/O and Security (大意:IO安全):
When using the classes in the System.IO namespace, operating system security requirements such as access control lists (ACLs) must be satisfied for access to be allowed. This requirement is in addition to any FileIOPermission requirements. (大意:当使用System.IO命名空间中的类时,必须满足操作系统的安全需要。)Note
ACLs can be managed programmatically. For more information, see How to: Add or Remove Access Control List Entries and ACL Technology Overview.Caution
Default security policy for the Internet and an intranet does not allow access to files. Therefore, do not use the regular nonisolated storage I/O classes if you are writing code that will be downloaded over the Internet. Use Isolated Storage instead.Caution
When a file or network stream is opened, a security check is performed only when the stream is constructed. Therefore, be careful when handing these streams off to less-trusted code or application domains.以上就是基本文件IO操作的相关类,看过之后,你脑袋多半里还是混沌一片,但你至少已经知道文件IO涉及了那些方面,比如,读,写,字节数组,字符串,文件,还有访问控制,这些“关键字”就是信息,之后就要靠你自己把这些信息,形成一个体系——文件IO。MSDN 给出了几个完整的例子,比如,如何读写二进制文件;如何读写文本文件;如何读写字符串等等,我觉得不错。我会在今后的文章中介绍。
如何向文本文件写入字符串
本文的例子来自MSDN。演示如何向一个文本文件写字符串。第一个例子演示如何向一个已经存在的文件添加文本。第二个例子演示如何创建一个新的文件,并向它写入一个字符串。WriteAllText方法也提供类似的功能。
例一
using System;
using System.IO;
class Test
{
public static void Main()
{
using (StreamWriter sw = new StreamWriter("TestFile.txt"))
{
sw.Write("This is the ");
sw.WriteLine("header for the file.");
sw.WriteLine("-------------------");
sw.Write("The date is: ");
sw.WriteLine(DateTime.Now);
}
}
}
例二
using System;
using System.IO;
public class TextToFile
{
private const string FILE_NAME = "MyFile.txt";
public static void Main(String[] args)
{
if (File.Exists(FILE_NAME))
{
Console.WriteLine("{0} already exists.", FILE_NAME);
return;
}
using (StreamWriter sw = File.CreateText(FILE_NAME))
{
sw.WriteLine ("This is my file.");
sw.WriteLine ("I can write ints {0} or floats {1}, and so on.", 1, 4.2);
sw.Close();
}
}
}
如何从文本文件读取字符串
下面的例子演示如何从文本文件读取字符串。其中,第二个例子添加了检测文件结束。通过ReadAll()和ReadAllText()方法能实现同样的功能。
例一
using System;
using System.IO;
class Test
{
public static void Main()
{
try
{
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
}
}
例二
using System;
using System.IO;
public class TextFromFile
{
private const string FILE_NAME = "MyFile.txt";
public static void Main(String[] args)
{
if (!File.Exists(FILE_NAME))
{
Console.WriteLine("{0} does not exist.", FILE_NAME);
return;
}
using (StreamReader sr = File.OpenText(FILE_NAME))
{
String input;
while ((input=sr.ReadLine())!=null)
{
Console.WriteLine(input);
}
Console.WriteLine ("The end of the stream has been reached.");
sr.Close();
}
}
}
如何读取数据文件
BinaryReader和BinaryWriter类用来读写数据,而不是字符串。下面的例子演示读写数据。
例子
using System;
using System.IO;
class MyStream
{
private const string FILE_NAME = "Test.data";
public static void Main(String[] args)
{
if (File.Exists(FILE_NAME))
{
Console.WriteLine("{0} already exists!", FILE_NAME);
return;
}
FileStream fs = new FileStream(FILE_NAME, FileMode.CreateNew);
BinaryWriter w = new BinaryWriter(fs);
for (int i = 0; i < 11; i++)
{
w.Write( (int) i);
}
w.Close();
fs.Close();
fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
for (int i = 0; i < 11; i++)
{
Console.WriteLine(r.ReadInt32());
}
r.Close();
fs.Close();
}
}
说明
如果Test.data文件在当前目录已经存在,会抛出IOException异常。
如何向字符串写入字符
下面的例子演示用StringWriter类向一个字符串写入字符数组中的字符。
例子
using System;
using System.IO;
using System.Text;
public class CharsToStr
{
public static void Main(String[] args)
{
StringBuilder sb = new StringBuilder("Some number of characters");
char[] b = {' ','t','o',' ','w','r','i','t','e',' ','t','o','.'};
StringWriter sw = new StringWriter(sb);
sw.Write(b, 0, 3);
Console.WriteLine(sb);
sw.Close();
}
}
如何从字符串读取字符
下面的例子演示用StringRead类从字符串读取字符。
例子
using System;
using System.IO;
public class CharsFromStr
{
public static void Main(String[] args)
{
String str = "Some number of characters";
char[] b = new char[24];
StringReader sr = new StringReader(str);
sr.Read(b, 0, 13);
Console.WriteLine(b);
sr.Close();
}
}