zoukankan      html  css  js  c++  java
  • Stream Part.2

    什么是 TextReader ?

           TextReader是一个对于Text的读取器,可是又是怎么读取的呢?当然是通过连续的字符进行读取。

           为什么在介绍StreamReader之前,要搞这个东东? 答案其实很简单:他们两个就是父子关系。

    TextReader 的常用属性和方法

           想象一下 Text 这个词的范围,它囊括了许多的文件类型,我们可以在记事本上使用任何语言(英语,中文,c# ,天书,javascript,jquery,xml,xaml,sql,c++……),如此多的语言文本归根结底还是通过一个个char组成的,所以微软构造出了TextReader这个抽象类。对于TextReader我们无法直接实例化,应为它是个抽象类,只有

    定义类的行为,不针对特定实现。

    1:具有一个protected类型的构造函数

    *2: void Close()方法:和上篇Stream一样,TextReader也有Close方法,我们必须牢记,在用完之后应该主动关闭它

    *3: void Dispose()方法:释放所有该TextReader 所持有的所有资源(包括TextReader中持有的stream或其他对象)

    *4: int Peek()方法:这个方法主要是寻找当前char的下个 char,当返回值是-1时,表示下个 char已经是最后一个位置的char了

    *5: int Read()方法:读取下一个char, 但是和peek方法不同,read()方法使指针指向下个字符,peek 还是指向原来那个字符

    *6: int Read(Char[] buffer,int index,int count)方法:将数据读入buffer数组

    *7: int ReadBlock(Char[] buffer,int index,int count)方法:和Read方法基本一致,效率上来说ReadBlock更高点,但ReadBlock并非属于线程安全,要注意。

    *8:virtual string ReadLine() 方法:读取每一行的数据并返回当前行的字符的字符串

    *9:virtual string ReadToEnd()方法:包含从当前位置到 TextReader 的结尾的所有字符的字符串。

    温故一下上述方法:

    static void Main(string[] args)
    {
        string text = "abc\nabc";
     
        using (TextReader reader = new StringReader(text))
        {
            while (reader.Peek() != -1)
            {
                Console.WriteLine("Peek = {0}", (char)reader.Peek());
                Console.WriteLine("Read = {0}", (char)reader.Read());
            }
            reader.Close();
        }
     
        using (TextReader reader = new StringReader(text))
        {
            char[] charBuffer = new char[3];
            int data = reader.ReadBlock(charBuffer, 0, 3);
            for (int i = 0; i < charBuffer.Length; i++)
            {
                Console.WriteLine("通过readBlock读出的数据:{0}", charBuffer[i]);
            }
            reader.Close();
        }
     
        using (TextReader reader = new StringReader(text))
        {
            string lineData = reader.ReadLine();
            Console.WriteLine("第一行的数据为:{0}", lineData);
            reader.Close();
        }
     
        using (TextReader reader = new StringReader(text))
        {
            string allData = reader.ReadToEnd();
            Console.WriteLine("全部的数据为:{0}", allData);
            reader.Close();
        }
     
        Console.ReadLine();
    }

    image

    StreamReader 的强大

           在对于流的操作中,StreamReader 对于流的读取方面非常重要,!文件的复制,移动,上传,下载,压缩,保存,远程FTP文件的读取,甚至于HttpResponse等等,只要是与流相关的任何派生类,StreamReader 都能够轻松处理,当然,大家甚至可以自定义相关的派生类去实现复杂的序列化。在实际项目,我们可能碰到过许多上述的情况,有时乱码的问题会让我们发狂,但是只要深刻去理解基础的话,就能找到适合的解决方法

    StreamReader 类的常用属性及方法

           其实StreamReader的一些方法已经在其父类TextReader中说的很仔细了,但是个人觉得构造函数和属性才是重点

    首先上构造函数

    *1: StreamReader(Stream stream)

           将stream作为一个参数放入StreamReader,这样的话StreamReader可以对该stream进行读取操作。

    *2: StreamReader(string string, Encoding encoding)

           这里的string对象不是简单的字符串,而是具体文件的地址,然后根据用户选择编码去读取流中的数据

    *3: StreamReader(string string,bool detectEncodingFromByteOrderMarks)      

           有时我们希望程序自动判断用何种编码去读取,这时候detectEncodingFromByteOrderMarks这个参数就能起作用了,当设置为true的时候数通过查看流的前三个字节来检测编码。如果文件以适当的字节顺序标记开头,该参数自动识别 UTF-8、Little-Endian Unicode 和 Big-Endian Unicode 文本,当为false 时,方法会去使用用户提供的编码。

    *4: StreamReader(string string, Encoding encoding, bool detectEncodingFromByteOrderMarks,int bufferSize)         

           这个方法提供了4个参数的重载,前3个我们都已经了解,最后1个是缓冲区大小的设置。

    *StreamReader 还有其他的一些构造函数,都是上述4个的扩充,所以本例就取上述的4个构造函数来说明

    属性:

    1:BaseStream

           获取基础流对象

    2:CurrentEncoding:

           获取当前的Encoding

    3:EndOfStream:

           判断StreamReader是否已经处于当前流的末尾

    最后,用FileStream的示例来温故下StreamReader

    static void Main(string[] args)
    {
        string txtFilePath = "D:\\TextReader.txt";
        char[] charBuffer2 = new char[3];
     
        // 利用 FileStream 类将文件文本数据变成流然后放入 StreamReader 构造函数中
        using (FileStream stream = File.OpenRead(txtFilePath))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                DisplayResultStringByUsingRead(reader);
            }
        }
     
        using (FileStream stream = File.OpenRead(txtFilePath))
        {
            // 使用 Encoding.ASCII来尝试下
            using (StreamReader reader = new StreamReader(stream, Encoding.ASCII, false))
            {
                DisplayResultStringByUsingReadBlock(reader);
            }
        }
     
        // 尝试用文件定位直接得到StreamReader,顺便使用 Encoding.Default
        using (StreamReader reader = new StreamReader(txtFilePath, Encoding.Default, false, 123))
        {
            DisplayResultStringByUsingReadLine(reader);
        }
     
        // 也可以通过 File.OpenText 方法直接获取到 StreamReader 对象
        using (StreamReader reader = File.OpenText(txtFilePath))
        {
            DisplayResultStringByUsingReadLine(reader);
        }
     
        Console.ReadLine();
    }
     
    /// <summary>
    /// 使用StreamReader.Read()方法
    /// </summary>
    public static void DisplayResultStringByUsingRead(StreamReader reader)
    {
        int readChar = 0;
        string result = string.Empty;
        while ((readChar = reader.Read()) != -1)
        {
            result += (char)readChar;
        }
        Console.WriteLine("使用StreamReader.Read()方法得到Text文件中的数据为 : {0}", result);
    }
     
    /// <summary>
    /// 使用StreamReader.ReadBlock()方法
    /// </summary>
    public static void DisplayResultStringByUsingReadBlock(StreamReader reader)
    {
        char[] charBuffer = new char[10];
        string result = string.Empty;
        reader.ReadBlock(charBuffer, 0, 10);
        for (int i = 0; i < charBuffer.Length; i++)
        {
            result += charBuffer[i];
        }
        Console.WriteLine("使用StreamReader.ReadBlock()方法得到Text文件中前10个数据为 : {0}", result);
    }
     
    /// <summary>
    /// 使用StreamReader.ReadLine()方法
    /// </summary>
    public static void DisplayResultStringByUsingReadLine(StreamReader reader)
    {
        int i = 1;
        string resultString = string.Empty;
        while ((resultString = reader.ReadLine()) != null)
        {
            Console.WriteLine("使用StreamReader.Read()方法得到Text文件中第{1}行的数据为 : {0}", resultString, i);
            i++;
        }
    }
  • 相关阅读:
    java 可变參数列表
    Java -Xms -Xmx -Xss -XX:MaxNewSize -XX:MaxPermSize含义记录
    hdu 4939
    什么是堆和栈,它们在哪儿?
    PPAPI插件与浏览器的通信
    Java&amp;Xml教程(十一)JAXB实现XML与Java对象转换
    Heavy Transportation
    Python学习笔记-小记
    C/C++知识要点5——智能指针原理及自己定义实现
    小米2S电池电量用尽充电无法开机解决方法
  • 原文地址:https://www.cnblogs.com/SkySoot/p/2570051.html
Copyright © 2011-2022 走看看