• 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平台的换行符————

  • 相关阅读:
    软件架构的认识
    软件需求十步走读书笔记3
    软件需求十步走读书笔记2
    系统利益相关者描述案例
    项目目标文档
    《需求工程-软件建模与分析》读书笔记2
    《需求工程-软件建模与分析》读书笔记1
    专业实训题目需求分析
    2015年秋季个人阅读计划
    课程改进意见
  • 原文地址:https://www.cnblogs.com/weststar/p/12741573.html
Copyright © 2020-2023  润新知