文件流
文件流
- 拷贝文件的两种方式:将源文件内容全部读到内存中,再写到目标文件中;读取源文件的1KB内存,写到目标文件中,再读取源文件的1KB内存,再写到目标文件中……。第二种方式就是一种流(Stream)的操作。
- 用File.ReadAllText、File.WriteAllText进行文件读写是一次性读、写,如果文件非常大会占内存、慢。需要读一行处理一行的机制,这就是流(Stream)。Stream会只读取要求的位置、长度的内容。
- 就像SqlConnection一样,Stream不会将所有内容一次性读取到内存中,有一个指针,指针指到哪里才能读、写到哪里。
- 流有很多种类,文件流是其中一种。FileStream类new FileStream(“c:/a.txt”, filemode, fileaccess)后两个参数可选值及含义自己看。 FileStream可读可写。可以使用File.OpenRead、File.OpenWrite这两个简化调用方法。
- 练习:文件加密(每一位用255-r)
- byte[]是任何数据的最根本表示形式,任何数据最终都是二进制。
- Write用于向当前位置写入若干字节,Read用户读取若干字节。(*)每次Read、Write指针都会自动后移。
- 文件流的Flush、Close、Dispose。缓冲区
- 更方便的用法:File.OpenRead,File.OpenWrite,内部还是new对象。
- Stream类是FileStream类的父类,有MemoryStream(内存流)、GZipStream (压缩解压流)、CryptoStream (加密流), GZipStream 、 CryptoStream 是装饰者模式的应用。尽量只操作父类Stream。
StreamWriter
- Stream把所有内容当成二进制来看待,如果是文本内容,则需要程序员来处理文本和二进制之间的转换。
- 用StreamWriter可以简化文本类型的Stream的处理
- StreamWriter是辅助Stream进行处理的
using (StreamWriter writer = new StreamWriter(stream, encoding))
{
writer.WriteLine("Hello World!!");
}
StreamWriter对Stream进行了包装,调一下writer.WriteLine背后帮我们做了把字符串转换为二进制的工作。
StreamRead
和StreamWriter类似, StreamReader简化了文本类型的流的读取。
Stream stream = File.OpenRead("c:/1.txt");
using (StreamReader reader = new StreamReader(stream,encoding))
{
//Console.WriteLine(reader.ReadToEnd());
Console.WriteLine(reader.ReadLine());
}
ReadToEnd用于从当前位置一直读到最后,内容大的话会占内存;每次调用都往下走,不能无意中调用了两次
ReadLine读取一行,如果到了末尾,则返回null。
WebClient的流操作
- WebClient OpenRead方法打开一个读取流(ReadLine好像有Bug);OpenWrite方法打开一个写入流。
- 案例:使用WebClient分析读取http服务器上的Excel文件,不用中间文件。
基于流方式进行操作的好处就是不用中间文件,没有安全性问题、没有文件冲突问题。
开发复杂一点程序的原则就是步步为营,不要想着一次写出来,比如这个案例就可以分解为:读取数据库、创建Excel、上传Excel三步,所以先读取数据库,然后WriteLine看看数据有没有被正确的读出来,ok再开发生成Excel的功能,先生成到FileStream中,成功了再最后完成上传到FTP的功能。这也是迭代的开发方式