zoukankan      html  css  js  c++  java
  • 12.3 字节流和字符流

    一、InputStream和Reader

    InputStream和Reader是所有输入流的基类,它们都是两个抽象类,本身并不能创建实例来执行输入,但它们将所谓所有输入流的模板,所以它们的方法是所有输入流都可使用的方法。它们包含如下三个方法:

    1.1 InputStream里包含的方法

    ★int read():从输入流中读取单个字节(相当于从图15.5所示水管中取出一滴水),返回所读取的字节数据(字节数据可直接转换为int类型)。
    ★int read(byte[] b):从输入流中读取最多b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
    ★int read(byte[] b, int off, int len):从输入流中读取最多len字节的数据,并将其存储在数组 b 中,放入b数组中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。

    1.2 Reader里包含的方法

    ★int read():从输入流中读取单个字符(2个字节)(相当于从图15.5所示水管中取出一滴水),返回所读取的字节数据(字节数据可直接转换为int类型)。
    ★int read(char[] cbuf):从输入流中读取最多cbuf个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
    ★int read(char[] cbuf, int off, int len):从输入流中读取最多len字节的数据,并将其存储在字符数组cbuf中,放入cbuf数组中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字符数。

    1.3 实例演示:

    InputStream和Reader所提供的方法,功能基本一致。InputStream和Reader都是将输入数据抽象成水管,程序通过read()方法来读取多个水滴。当使用数组时作为read()方法的参数时,可以理解为使用一个“竹筒”到如图所示的水管中取水。程序从数据流中取出水后,记录指针自动后移,多次重复这个取水过程,直到最后,read()方法返回-1,即表示到达数据流的结束点。

    InputStream和Reader是所有输入流的基类,它们都是两个抽象类,本身并不能创建实例来执行输入,它们分别有一个用于读取文件的输入流:FileInputSream和FileReader,它们都是节点流——会直接和指定文件相关联。
    下面示范使用了FileInputStream流来读取自身的效果:

    package section3;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class FileInputStreamTest
    {
        public static void main(String[] args)
                throws IOException
        {
            //创建字节输入流
            var fis=new FileInputStream("src\section3\FileInputStreamTest.java");
            //创建一个长度为1024的“竹筒”
            byte[] bbuf=new byte[1024];
            //用于保存实际读到的字节数
            var hasRead=0;
            //使用循环重复“取水”的过程
            while((hasRead=fis.read(bbuf))>0)
            {
                //从竹筒中取出“水滴”(字节),将字节数组转换为字符串输出
                System.out.println(new String(bbuf,0,hasRead));
            }
            //关闭文件输入流,放在finally块里更安全
            fis.close();
        }
    }
    

    下面演示使用FileReader来读取文件自身

    package section3;
    
    import java.io.FileReader;
    import java.io.IOException;
    
    public class FileReaderTest
    {
        public static void main(String[] args) {
            try (
                    //创建字符输入流
                    var fr = new FileReader("src\section3\FileReaderTest.java")
            ) {
                //创建一个长度为32的“竹筒”
                var cbuf = new char[32];
                //用于保存实际读到的字节数
                var hasRead = 0;
                //使用循环重复“取水”的过程
                while ((hasRead = fr.read(cbuf)) > 0) {
                    //从竹筒中取出“水滴”(字节),将字节数组转换为字符串输出
                    System.out.println(new String(cbuf, 0, hasRead));
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    

    1.4 InputStream和FileReader提供的移动指针的方法

    (1)void mark(int readAheadLimit):在记录指针的当前位置记录一个标记。
    (2)boolean markSupported():判断此输入流是否指出mark()操作,即是否支持记录标记。
    (3)void reset():将记录指针重新定位到上一次记录标记的位置。
    (4)long skip(long n):记录指针向前移动n个字节/字符。

    二、OutputStream和Writer

    OutputStream和Writer也非常相似,两个流都提供了如下三个方法:
    ★void write(int c):将指定的字节/字符输出到输出流中,其中c既可以代表字节,也可以代表字符。
    ★void write(byte[]/char[] buf):将字节数组/字符数组中的数据输出到指定输出流中。
    ★void write(char[] cbuf, int off, int len):将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到输出流中。
    因为字符流直接以字符作为操作单位,所以writer可以用字符串作为字符数组,即以String对象作为参数。writer里还包含如下方法:
    ★void write(String str):将str字符串里包含的字符输出到指定流中。
    ★void write(String str,int off,int len):将str字符串从off位置开始,长度为len的字符输出到指定的输出流中。
    下面程序使用FileInputStream来执行输入,并使用FileOutputStream来执行输出,用以实现FileOutputStreamTest.java文件的功能。

    package section3;
    
            import java.io.FileReader;
            import java.io.IOException;
    
    public class FileReaderTest
    {
        public static void main(String[] args) {
            try (
                    //创建字符输入流
                    var fr = new FileReader("src\section3\FileReaderTest.java")
            ) {
                //创建一个长度为32的“竹筒”
                var cbuf = new char[32];
                //用于保存实际读到的字节数
                var hasRead = 0;
                //使用循环重复“取水”的过程
                while ((hasRead = fr.read(cbuf)) > 0) {
                    //从竹筒中取出“水滴”(字节),将字节数组转换为字符串输出
                    System.out.println(new String(cbuf, 0, hasRead));
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    

    运行上面程序,即看到在当前路径下多了一个文件:newFile.txt,该文件的内容和FileOutputStreamTest.java文件内容相同。
    如果希望直接输出字符串内容,即使用writer会由更好的效果,如下程序所示:

    package section3;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class FileWriterTest
    {
        public static void main(String[] args)
        {
            try(
                    var fw=new FileWriter("src\section3\poem.txt")
                    )
            {
                fw.write("锦瑟 - 李商隐
    ");
                fw.write("锦瑟无端五十弦,一弦一柱思华年。
    ");
                fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。
    ");
                fw.write("沧海月明珠有泪,蓝田日暖玉生烟。
    ");
                fw.write("此情可待成追忆,只是当时已惘然。
    ");
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    注意:widows平台的换行符————

  • 相关阅读:
    HDU 2955 Robberies(01背包)
    HDU 2602 Bone Collector(01背包)
    HUST 1352 Repetitions of Substrings(字符串)
    HUST 1358 Uiwurerirexb jeqvad(模拟解密)
    HUST 1404 Hamming Distance(字符串)
    HDU 4520 小Q系列故事――最佳裁判(STL)
    HDU 2058 The sum problem(枚举)
    【破解】修改程序版权、添加弹窗
    HDU 1407 测试你是否和LTC水平一样高(枚举)
    HDU 1050 Moving Tables(贪心)
  • 原文地址:https://www.cnblogs.com/weststar/p/12741573.html
Copyright © 2011-2022 走看看