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. 使用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) 指定编码名称,字节流转换为字符流

在这里插入图片描述

示例: 将字节流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();
}

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

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+"保存文件成功");
}

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


打印流:

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

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!");//输出到文件
}

PrintWriter

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

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

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对象时却会产生编译时的警告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苗半里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值