1、编码:

计算机只能识别二进制格式的数据,也就是0和1组成的数据

那么计算机是怎么识别英文的呢?

是因为计算机刚出来的时候,老外就编了一套字符编码,叫ASCII码,用不同的ASCII码对应不同的英文以及英文标点符号等!然后再转换成二进制格式

ASCII表图在下面,计算英文字符在计算机中表示的ASCII码:

 

因为计算机是老外发明的,所以老外就没考虑到其他语言的情况,所以计算机标准的ASCII码只能存英文以及英文的标点符号等,不能存其他语言!

但是假如我要存其他语言呢,计算机该怎么识别呢?

以中文为例:在计算机初期,已经有各种各样的编码对汉字“海”进行了编码并存进了计算机,下面我们就来看下不同编码对“海”字所存储的编码信息

 

可以看出,不同编码存储的信息是不一样的!所以这也就强调了用什么编码保存的文件,就用什么编码打开!不然就会造成乱码! 最好使用国际推荐编码:UTF-8

Encoding.Default使用的是操作系统的当前 ANSI 代码页的编码。

2、文本文件

文本文件可以用不同的编码方式来存储为二进制格式:UTF-8,ASCII,Unicode等

如果出现乱码,一般都是编码的问题,用什么编码保存,就应该用什么编码格式打开,

文本文件相关联的函数一般都有一个Encoding类!

什么是文本文件,能拖到记事本中,并能看得懂的文件就是文本文件,doc不是!

关键类:File操作文件,Directory操作目录(文件夹),Path操作路径(是路径字符串进行的操作)!

3、流

File.ReadAllTextFile.WriteAllText进行文件读写是一次性读写,如果文件非常大,会占内存、慢!

需要读一行处理一行的机制,这就是流,Stream会读取要求的位置,长度的内容!

Stream不会将所有的内容一次性读取到内存中,有一个指针,指针指到哪里才能读写到哪里!

流有很多种类:文件流是其中一种,FileStream

byte[]是任何数据最根本的表示形式,任何数据最终都是二进制。

            using (FileStream fs = new FileStream(@"C:\Users\ZWH\Desktop\Dos命令.txt", FileMode.Open))
            {
                using (FileStream fs2 = new FileStream(@"C:\Users\ZWH\Desktop\Dos赋值.txt", FileMode.CreateNew))
                {
                    byte[] b = new byte[1024 * 1024 * 4]; //4M
                    int getv = 0;
                    //getv表示实际读了多长的内容
                    while ((getv = fs.Read(b, 0, b.Length)) > 0)
                    {
                        fs2.Write(b, 0, getv);
                    }
                }
            }

 Flush,Close,Dispose: 

            FileStream fs = new FileStream("c:\\1a.txt", FileMode.Create);
            string result = "1234";
            byte[] b = Encoding.UTF8.GetBytes(result);
            fs.Write(b, 0, b.Length);

 执行上面代码,发现1a.txt文件里面的内容是空的,这就涉及到了文件的Flush,Close,Dispose相关知识了,

我们对FileStream的Write方法进行反编译,逐步查看此方法调用了那些东西,可以看到下面这段:

这就说明了,此方法会调用C++语言的动态库,这就属于非托管程序了,.net不知道此方法什么时候会执行结束,也就脱离了.net的管辖范围,

这就表示什么时候向文件里面写入流是不确定的!系统会把流全部积攒到内存中去!等到系统空闲的时候再写到文件中去!

操作系统会帮我们优化(等到空闲时去处理),如果你不想它帮我们优化,就使用Flush强制去执行就行了!

Flush方法是清理缓冲区,把缓冲区中的数据全部写到文件中去!

那么只要代码最后面加句Flush即可!

fs.Flush();//但是我们不应该手动调用Flush,而是使用Close方法!

fs.Close();//会把没有写入缓冲区的数据写入文件(Flush)再关闭

最佳方式:就是使用Using,因为Using会调用Dispose,Dispose会调用Close,而Close会调用Flush,所以最好使用Using!自己可以反编译去看!

Dispose:  //执行与释放或重置非托管资源相关的应用程序定义的任务。

如果using,Flush,CLose,Dispose都不使用的话,那么就必须等应用程序结束,流才能全部写入文件

因为应用程序结束的话,FileStream被释放,也就是被Dispose了,自然而然流会被写入文件,

如果此段代码是放在一个click事件里面执行的话,照理由这个click事件返回,FileStream会被释放,但是发现文件还是无法立即写入的!

因为FileStream并没有被立即释放

File.OpenWrite和File.OpenRead:

这俩个方法主要是为了使用方便而已,没什么特别的!File.OpenWrite和File.OpenRead内部还是new了FileStream,自己可以反编译看下!

FileStream fs = new FileStream("c:\\1a.txt", FileMode.Create)   就等于   FileStream fs = File.OpenWrite("c:\\1a.txt");

FileStream fs = new FileStream("c:\\1a.txt", FileMode.Open)    就等于   FileStream fs = File.OpenRead("c:\\1a.txt");

Stream:

Stream类是FileStream(文件流)类的父类,有MemoryStream(内存流)GZipStream(压缩解压流)CryptoStream(加密流),尽量使用父类Stream!

GZipStream压缩

           using (FileStream fs = File.OpenWrite(@"c:\11.txt"))
            {
                using (GZipStream gz = new GZipStream(fs, CompressionMode.Compress))
                {
                    byte[] b = Encoding.UTF8.GetBytes("Hello World");
                    gz.Write(b, 0, b.Length);
                }
            }

GZipStream解压

           using (FileStream fs = File.OpenRead(@"c:\11.txt"))
            {
                using (GZipStream gz = new GZipStream(fs, CompressionMode.Decompress))
                {
                    using (FileStream fs2 = File.OpenWrite(@"c:\11a.txt"))
                    {
                        int getByte;
                        byte[] b = new byte[1024 * 1024 * 4];
                        while ((getByte = gz.Read(b, 0, b.Length)) > 0)
                        {
                            fs2.Write(b, 0, getByte);
                        }
                    }
                }
            }

.Net开源的压缩组件还有:ZIP-DotNetZip,7Zip-SevenZipSharp,综合-SharpCompress

详见:http://www.cnblogs.com/asxinyu/archive/2013/03/05/2943696.html

 

CryptoStream加密、解密 

  class Program
    {
        static void Main(string[] args)
        {
            Rijndael rijndael = Rijndael.Create();
            byte[] key = rijndael.Key;
            byte[] iv = rijndael.IV;

            using (Stream readStream = File.OpenRead(@"d:\原文.txt"))
            {
                using (Stream writeStream = File.OpenWrite(@"d:\加密之后.txt"))
                {
                    using (CryptoStream cs = new CryptoStream(writeStream, rijndael.CreateEncryptor(key, iv), CryptoStreamMode.Write))
                    {
                        byte[] b = new byte[1024 * 1024 * 2];
                        int readlength = 0;
                        while ((readlength = readStream.Read(b, 0, b.Length)) > 0)
                        {
                            cs.Write(b, 0, readlength);
                        }
                    }
                }
            }

            Console.WriteLine("加密完成!按任意键进行解密!");
            Console.ReadKey();

            using (Stream readStream = File.OpenRead(@"d:\加密之后.txt"))
            {
                using (Stream writeStream = File.OpenWrite(@"d:\解密之后.txt"))
                {
                    using (CryptoStream cs = new CryptoStream(readStream, rijndael.CreateDecryptor(key, iv), CryptoStreamMode.Read))
                    {
                        byte[] b = new byte[1024 * 1024 * 2];
                        int readlength = 0;
                        while ((readlength = cs.Read(b, 0, b.Length)) > 0)
                        {
                            writeStream.Write(b, 0, readlength);
                        }
                    }
                }
            }
            Console.WriteLine("解密完成!按任意键退出程序!");
            Console.ReadKey();
        }
    }

 StreamReader和StreamWriter

简化了对文本类型流的读取

            using (FileStream fs = File.OpenRead(@"c:\11.txt"))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    //Console.WriteLine(sr.ReadToEnd()); // 用于从当前位置读到最后的位置,内容大的话会占内存
                    string text = string.Empty;
                    while ((text = sr.ReadLine()) != null)//读取一行,如果读到了末尾,则返回null
                    {
                        Console.WriteLine(text);
                    }
                }
            }
            using (FileStream fs = File.OpenWrite(@"c:\11.txt"))
            {
                using (StreamWriter sr = new StreamWriter(fs))
                {
                    sr.Write("123");
                    //sr.WriteLine("456");
                }
            }

网络流:System.Net.ConnectStream

            WebClient wc = new WebClient();
            //wc.DownloadFile("http://www.baidu.com/1.doc", @"c:\1.doc");//不建议使用!
            Stream s = wc.OpenRead("http://www.baidu.com/1.doc");//建议使用这种流的方式读取,打断点可以看出s为System.Net.ConnectStream类型
            int getByte = 0;
            byte[] b = new byte[1024 * 1024 * 4];
            using (s)
            {
                while ((getByte = s.Read(b, 0, b.Length)) > 0)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        ms.Write(b, 0, getByte);
                    }
                }
            }
//因为有的Stream子类不支持指针的后退、Seek,而使用NPOI对excel进行操作时,HSSFWorkbook要求传入一个指针能随意移动的流memstream,而上面的网络流s不支持,所以把网络流转换成内存流即可!内存流支持!
                HSSFWorkbook workbook = new HSSFWorkbook(memstream);
                HSSFSheet sheet = workbook.GetSheetAt(0);
                HSSFRow row = sheet.GetRow(0);
                MessageBox.Show(row.GetCell(0).StringCellValue);

 

posted @ 2015-03-10 23:23  MrZivChu  阅读(535)  评论(0编辑  收藏  举报
分享按钮