• Java标准输入输出流【转换流&打印流】


    ➤ Java 输入输出IO流 全部导航

    类型默认设备
    System.in 标准输入InputStream键盘
    System.out 标准输出PrintStream显示器
    System类的 public final static InputStream in = null;
    		   public final static PrintStream in = null;
    标准输入:
    System.in  编译类型  InputStream
    System.in  运行类型  BufferedInputStream
    
    System.out.print(System.in.getClass());
    输出为 class java.io.BufferedInputStream 
    
    标准输出:
    System.out  编译类型  PrintStream
    System.out  运行类型  PrintStream
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    乱码转换【转换流】

    字节流 ----> 字符流 即 转换流

    通过一个例子引出乱码转换问题:

    1. 使用BufferedReader 对象读取一个txt文件
    2. txt文件默认编码方式是 UTF-8
    3. 由图中可以看到是正常读取的,没有问题

    在这里插入图片描述

    但是 把文件编码方式改成 ANSI 之后,再进行读取时:

    在这里插入图片描述

    在这里插入图片描述
    发现出现了乱码,没有正常读取到文件内容;

    可以这样解决:

    1. 将字节流以指定编码方式读取(GBK、UTF-8、ISO8859、ANSI等等);
    2. 再通过转换流 转换为字符流 即可;

    转换流有:

    • InputStreamReader
    • OutputStreamWriter

            当处理纯文本数据时,使用字符流效率更高,并且可以有效解决中文乱码问题,所以建议将字节流转换为字符流:

    InputStreamReader

    • Reader的子类,可以将InputStream(字节流)包装成Reader(字符流);
    InputStreamReader的构造器:(属于字符流)
    
    InputStreamReader(InputStream) 字节流转换为字符流
    
    InputStreamReader(InputStream,Charset) 以指定编码方式Charset,字节流转换为字符流
    
    InputStreamReader(InputStream,CharsetDecoder) 给定一个字符解码器CharsetDecoder,字节流转换为字符流
    
    InputStreamReader(InputStream,String) 指定编码名称,字节流转换为字符流
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    示例: 将字节流FileInputStream包装成字符流InputStreamReader,对文件进行按UTF-8编码读取,进而在包装成 BufferedReader

    /*
    演示使用InputStreamReader转换流解决中文乱码问题
    将字节流FileInputStream转成字符流InputStreamReader,指定编码GBK/UTF-8
     */
    public static void main(String[] args) throws Exception{
        String filePath = "d:\\hello.txt";
        //1.把FileInputStream转成InputStreamReader (字节流转为字符流)
        //2.指定编码 gbk
        InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "GBK");
        //3.把InputStreamReader传入BufferedReader
        BufferedReader br = new BufferedReader(isr);
        /*
        为了简化 可以将 2 和 3 合在一起
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "GBK"));
         */
        //4.读取
        String s = br.readLine();
        System.out.println("读取内容:\n"+s);
        //5.关闭外层流
        br.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    可以看出 运行结果读取正常:
    在这里插入图片描述

    OutputStreamWriter

    • Writer的子类,可以将OutputStream(字节流)包装成Writer(字符流);

    类比 InputStream 有如下关系 及 构造器:

    在这里插入图片描述

    示例:将字节流 FileOutputStream 包装成 字符流 OutputStreamWriter,对文件进行写入(按gbk编码方式,也可以指定其他。如 utf-8)

    /*
    演示 OutputStreamWriter 使用
    把 FileOutputStream 字节流 转为 字符流 OutputStreamWriter
    指定编码 gbk/utf-8/utf8
     */
    public static void main(String[] args) throws Exception{
        String filePath = "d:\\yes.txt";//提前创建
        String charset = "utf8";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath),charset);
        osw.write("Hi 祝你天天开心!");
        osw.close();
        System.out.println("按照"+charset+"保存文件成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:
    在这里插入图片描述
    改变编码方式:
    在这里插入图片描述


    打印流:

    打印流只有输出流,没有输入流

    PrintStream & PrintWriter(两者区别在文章末尾)

    PrintStream

    在这里插入图片描述

    在这里插入图片描述

    /*
    		演示PrintStream(字节打印流/输出流)
     */
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;
        //在默认情况下PrintStream输出数据的位置是标准输出即显示器
        /*
            public void print(String s) {
                if (s == null) {
                    s = "null";
                }
                write(s);
            }
         */
        out.print("Java");
        //因为print底层使用的是write方法,所以可以直接调用write进行打印/输出
        out.write("你好".getBytes());
        out.close();
        //可以修改打印输出流的位置/设备
        /*
        public static void setOut(PrintStream out) {
             checkIO();
             setOut0(out); //native()方法,修改out
        }
         */
        //输出到文件
        System.setOut(new PrintStream("d:\\hello.txt"));
        System.out.println("Hello World!");//输出到文件
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    PrintWriter

    在这里插入图片描述
    在这里插入图片描述

    //	演示 PrintWriter 使用方式
    public static void main(String[] args) throws IOException {
        PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\hello.txt"));
        printWriter.print("你好Java");
        printWriter.close();//如果不关闭,就无法写入
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    PrintStream 和 PrintWriter 的区别:

    1. Stream用于二进制文件(非文本) ,Writer/Reader用于文本文件(虽然也是二进制,不过是按照一定的字符编码规则,不像前者) ,当然Stream也可用于文本,只不过比Writer/Reader来的麻烦;
    2. PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。
    3. Java的一个字符(char)是16bit的,一个byte是8bit的。PrintStream是写入一串8bit的数据的,PrintWriter是写入一串16bit的数据的。String缺省是用UNICODE编码,是16bit的。因此用PrintWriter写入的字符串,跨平台性会好一些,PrintStream的可能会出现字符集乱码。
    4. PrintStream是OutputStream的子类,PrintWriter是Writer的子类,两者处于对等的位置上,所以它们的API是非常相似的;二者区别不大;
    5. PrintStream类是过滤器类中一个不可忽视的成员,最基本的标准输出就要借助于它——我们常用的System.out变量就是PrintStream实例。与之对应的字符流类是PrintWriter类。
    6. PrintWriter类是JDK1.1版增加了与字节流I/O相对应的字符流I/O。但是,为了保持兼容性,原先的类几乎没有改动。再加之调试的需要,PrintStream类被保留,并且System类中的成员变量out、err仍作为它的对象。然而,PrintWriter用于大多数输出比PrintStream更为合适。因此1.1版的API中建议新开发的代码使用PrintWriter类,并将PrintStream类的两个构造函数标记为过时。这样,虽然使用System.out输出不会产生问题,在程序中创建新的PrintStream对象时却会产生编译时的警告。
  • 相关阅读:
    FMC子卡设计原理图:FMCJ450-基于ADRV9009的双收双发射频FMC子卡
    001 手把手用Git,Git从入门到上传本地项目到Github,看这篇就够了
    SpringCLoud——服务的拆分和远程调用
    冥想第六百零三天
    运维小技能:centos安装宝塔
    融云观察:AI Agent 是不是游戏赛道的下一个「赛点」?
    frp隧道(流量代理)
    Django TypeError: Abstract models cannot be instantiated.错误解决方案
    libmp3lame的接口使用
    DCM09- ReadDataByIdentifier ($22)的功能和配置【基于DaVinci Configurator Classic】
  • 原文地址:https://blog.csdn.net/Lov1_BYS/article/details/127950994