• 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:UsersWHDesktopDos命令.txt", FileMode.Open))
                {
                    using (FileStream fs2 = new FileStream(@"C:UsersWHDesktopDos赋值.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);
  • 相关阅读:
    动态规划算法-3
    动态规划算法-2
    动态规划算法-1
    滑动窗口算法-3
    央行副行长提示金融风险:地方偿债高峰期到来
    银行卡换“芯” 更要银行换心
    破解IT运维成本困境,专业化分工是妙方
    php连接mysql
    ajax原生验证用户名是否存在
    ajax跨域问题
  • 原文地址:https://www.cnblogs.com/MrZivChu/p/stream.html
Copyright © 2020-2023  润新知