➤ Java 输入输出IO流 全部导航
文章目录
- 乱码转换【转换流】
- InputStreamReader
- OutputStreamWriter
 
- 打印流:
- PrintStream
- PrintWriter
 
| 类型 | 默认设备 | |
|---|---|---|
| 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
乱码转换【转换流】
字节流 ----> 字符流 即 转换流
通过一个例子引出乱码转换问题:
- 使用BufferedReader 对象读取一个txt文件
- txt文件默认编码方式是 UTF-8
- 由图中可以看到是正常读取的,没有问题

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


 发现出现了乱码,没有正常读取到文件内容;
可以这样解决:
- 将字节流以指定编码方式读取(GBK、UTF-8、ISO8859、ANSI等等);
- 再通过转换流 转换为字符流 即可;
转换流有:
- 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 的区别:
- Stream用于二进制文件(非文本) ,Writer/Reader用于文本文件(虽然也是二进制,不过是按照一定的字符编码规则,不像前者) ,当然Stream也可用于文本,只不过比Writer/Reader来的麻烦;
- PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。
- Java的一个字符(char)是16bit的,一个byte是8bit的。PrintStream是写入一串8bit的数据的,PrintWriter是写入一串16bit的数据的。String缺省是用UNICODE编码,是16bit的。因此用PrintWriter写入的字符串,跨平台性会好一些,PrintStream的可能会出现字符集乱码。
- PrintStream是OutputStream的子类,PrintWriter是Writer的子类,两者处于对等的位置上,所以它们的API是非常相似的;二者区别不大;
- PrintStream类是过滤器类中一个不可忽视的成员,最基本的标准输出就要借助于它——我们常用的System.out变量就是PrintStream实例。与之对应的字符流类是PrintWriter类。
- PrintWriter类是JDK1.1版增加了与字节流I/O相对应的字符流I/O。但是,为了保持兼容性,原先的类几乎没有改动。再加之调试的需要,PrintStream类被保留,并且System类中的成员变量out、err仍作为它的对象。然而,PrintWriter用于大多数输出比PrintStream更为合适。因此1.1版的API中建议新开发的代码使用PrintWriter类,并将PrintStream类的两个构造函数标记为过时。这样,虽然使用System.out输出不会产生问题,在程序中创建新的PrintStream对象时却会产生编译时的警告。




![[附源码]SSM计算机毕业设计基于社区生鲜配送系统JAVA](https://img-blog.csdnimg.cn/37fc810373d64b4e84bd8f10018f2977.png)




![[附源码]计算机毕业设计JAVA篮球装备商城系统](https://img-blog.csdnimg.cn/eca4c536b1104aeca9ae2d8939dc3d54.png)









