目录
文件字节输入流(标准输入流) FileInputStream
应用:制作一个打印日志 + 恢复System输出流指向控制台
16个 重要的IO流简介(标蓝的为重点)
【文件流】
作用:读取文件
FileInputStream(字节流 | 标准输入流) FileOutputStream(字节流) FileReader(字符流) FileWriter(字符流)
【缓冲流】
作用:缓冲流自带缓冲区,使用的时候无需自定义char[ ]或者byte[ ]。
缓冲流也称为处理流,对文件或者其他目标频繁的操作,效率低,性能差。缓冲流目的是提高程序读取和写出的性能。
BufferedInputStream(字节流) BufferedOutputStream(字节流) BufferedReader(字符流) BufferedWriter(字符流)
【对象流】
作用:将对象序列化和反序列以保存
ObjectInputStream(字节流) ObjectOurputStream(字节流)
【数据流】
作用:可以将数据的类型如 num 是int型一并写入文件。(但是该文件不是文本文件,使用记事本打开是乱码的,有效保证了安全性)
DataInputStream(字节流) DataOutputStream(字节流)
【标准输出流】
作用:FileInputStream是标准输入流,相对的,标准输出流却不是FileOutputStream而是PrintStream
PrintStream(字节流 | 标准输出流) PrintWriter(字符流)
【字节流 转换 字符流】
字节流:按字节读取文件;字符流:按字符读取文件。
作用:把一个传递字节的节点流用于字符流,则我们需要使用转换流,先转化再传递
InputStreamReader OutputStreamWriter
Java IO体系
含有 Stream 的都是字节相关的流,含有 der 的都是字符相关的流

根据测试,文件路径以【当前用户根目录的路径】为相对路径
下面介绍一下File类
File类,和下面介绍的流,没有任何关系。File是任意的文件、或者任意的目录。即:“文件和路径名”的抽象表现形式
我们主要需要掌握构造方法、对象方法、及其相关应用
语法如下
- File file = new File ( 路径/文件路径 ); //构造方法
- file . exists ( ); //判断文件或目录是否存在(存在则返回boolean):
- file . isDirectory( ); //判断是否是一个目录(是则返回boolean)
- file . isFile( ); //判断是否是一个文件(是则返回boolean)
- file . getParent( ); //返回此抽象路径名父目录的路径字符串。若不存在,则返回null
- file . getParentFile( ); //返回此抽象路径名父目录的路径的File类对象。不存在则返回null
- file . getAbsolutePath( ); //返回此抽象路径名的绝对路径字符串
- file . getAbsoluteFile( ); //返回此抽象路径名的绝对路径的File类对象
- file . length( ); //获取文件的大小,返回一个表示文件字节大小的long值
- file . lastModified( ); //获取文件的最后一次修改时间,返回1970年到现在的毫秒long值
- file . listFiles( ); //获取当前目录下所有的子文件及目录,返回一个File数组
Properties集合简介
主要用于读取Java的配置文件。
Properties是一个Map体系集合类,因为其继承于Hashtable,而Hashtable继承于Dictionary类,实现了Map接口,所以Properties也保留了其相关特性。
Properties的特点
(1)Properties是Hashtable
(2)Properties类表示了一个可持久的属性集;
(3)Properties可以保存在流中或从流中加载;
(4)Properties中每个键和对应的值都是一个字符串(String类型);
(5)Properties有一个特殊的作用:专门用来加载xxx.properties配置文件。
Properties的使用
- //Properties作为map集合的使用
- private static void PropertiesMap() {
- Properties pro = new Properties();//不需要加泛型,所有的键值都是object类型
-
- //存储元素
- pro.put(001, "张三");
- pro.put(002, "李四");
- pro.put(003, "王五");
-
- //遍历集合
- for(Object key : pro.keySet()) {
- System.out.println(key + ":" + pro.get(key));
- }
- }
- /**
- * Properties作为集合的特有方法
- * 0bject setProperty(String key,String value):设置类合的链和值,都是String类型,底层调用Hashtable方法put
- * string getProperty ( String key):使用此属性列表中指定的性搜索属性
- * Set
stringPropert yNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 - */
- private static void SpecialMethod() {
- Properties pro = new Properties();
-
- pro.setProperty("001", "张三");//键值都是String类型
- pro.setProperty("002", "李四");
- pro.setProperty("003", "王五");
-
- System.out.println(pro.getProperty("001"));//根据键搜索属性
- System.out.println(pro.getProperty("0011"));//没有时返回null
-
- System.out.println(pro);
-
- Set
s = pro.stringPropertyNames();//返回一个不可修改的键集,其中键及其对应的值是字符串 - System.out.println(s);
- for(String key : s) {
- System.out.println(key + ":" + pro.getProperty(key));
- }
- }
Peoperties 通过 IO,结合 .properties文件使用
- //集合中数据保存到文件
- Properties pro = new Properties();
-
- pro.setProperty("001", "张三");//键值都是String类型
- pro.setProperty("002", "李四");
- pro.setProperty("003", "王五");
-
- System.out.println(pro);
-
- FileWriter fw = new FileWriter("Properties.properties");
- pro.store(fw,null);//不想添加描述信息就令第二个参数为null
-
- //数据保存为XML格式文件
- //storeToXML(OutputStream os, String comment, String encoding)使用指定的编码方式表示此表中包含的所有属性的XML文档
- FileOutputStream f1 = new FileOutputStream("PropertiesXML.XML");
- pro.storeToXML(f1, null);
- //文件中数据加载到集合
- Properties prop = new Properties();
-
- FileReader fr = new FileReader("Properties.properties");
- prop.load(fr);
-
- //将此属性列表打印到指定的输出流。此方法对于调试很有用
- prop.list(System.out);
- //System.out.println(prop);
-
- //从内容为XML格式的文件中读取数据加载为集合
- FileInputStream f2 = new FileInputStream("PropertiesXML.XML");
- prop.loadFromXML(f2);
-
- prop.list(System.out);
- //System.out.println(prop);
FileInputStream(字节流) FileOutputStream(字节流) FileReader(字符流) FileWriter(字符流)
字节流可以读取任意类型的文件,而字符流只能读取 文本文件 .txt
- public static void main(String[] args){
- try{
- //创建FileInputStream对象
- FileInputStream in = new FileInputStream(String path); //不追加读写
- //FileInputStream in = new FileInputStream(String path , true); //追加读写
-
- //创建字节数组
- byte[] b = new byte[1024];
- int len = 0;
- //一次读取最多字节数组大小的字节长度,并把读取到的字节赋值给字节数组
- while((len = in.read(b)) != -1){
- System.out.println(new String(b , 0 , len));
- }
-
- //关闭IO流
- in.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- public static void main(String[] args){
- try{
- //创建FileOutputStream对象
- FileOutputStream out = new FileOutputStream(String path);
- String str = "XXX";
-
- //写入字节
- out.write(str.getBytes());
-
- //缓冲、关闭IO流
- out.flush();
- out.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- public class FileReaderClass {
- public static void main(String[] args) {
- FileReader reader = null;
-
- try {
- //创建字符输入流
- reader = new FileReader("F:\\Java\\IOPractice\\FileReaderTXT.txt");
-
- //创建字符数组和中介数i
- char[] array = new char[2];
- int i=0;
-
- //一次读取最多字符数组长度的字符个数,并把字符赋值给字符数组
- while((i=reader.read(array))!=-1){
- String mid = new String(array,0,i);
- System.out.print(mid);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public class FileWriterClass {
- public static void main(String[] args) {
- FileWriter out = null;
-
- try {
- out = new FileWriter("F:\\Java\\IOPractice\\FileWriterTXT.txt",true);
-
- char[] array = {'C','S'};
- out.write(62); // >
- out.write(array); //可莉
- out.write("klee"); //klee
-
-
-
- out.flush();//输出流要记得刷新
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- try {
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- //复制文件
- public class CopyFile {
- public static void main(String[] args) {
- //外部建立一个空输入流、输出流
- FileInputStream filein = null;
- FileOutputStream fileout = null;
-
-
- try {
- //创建输入流、输出流对象
- filein = new FileInputStream("F:\\Java\\IOPractice\\copyTXT.txt");
- fileout = new FileOutputStream("F:\\Java\\IOPractice\\" +"copyGoalTXT.txt",true);//追加读写
-
- //【核心】一边读,一边写
- //假设我们复制一个大小为1738kb的文件
- byte[] bytes = new byte[1024]; /*一次copy 1024k 的文件*/
- int readCount = 0;
- while((readCount = filein.read(bytes)) != -1){
- fileout.write(bytes,0,readCount);
- }
-
- //刷新输出流
- try {
- fileout.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- //关闭输入流(建议分开try..catch,不至于一个异常 都无法关闭)
- try {
- filein.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- //关闭输出流
- try {
- fileout.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public class copyTXT {
- public static void main(String[] args) {
- FileReader in = null;
- FileWriter out = null;
-
- try {
- in = new FileReader("F:\\JAVA\\IOPractice\\copyTXT.txt");
- out = new FileWriter("F:\\JAVA\\IOPractice\\copyGoalTXT.txt");
-
- char[] charArr = new char[1024];
- int readCount = 0;
- while((readCount = in.read(charArr))!=-1){
- out.write(charArr,0,readCount);
- }
-
- out.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
缓冲流简介
BufferedInputStream(字节流) BufferedOutputStream(字节流) BufferedReader(字符流) BufferedWriter(字符流)
缓冲流也称为处理流,对文件或者其他目标频繁的操作,效率低,性能差。缓冲流目的是提高程序读取和写出的性能。
缓冲流的基本原理,是创建流对象时候,会创建一个内置的默认大小的缓冲区数组,通过缓冲区书写.使得性能大大提升
因此相比于 文件流,缓冲流无需通过数组作为中介进行流的传输
缓冲流的使用
以 BufferedWriter 缓冲输入字节流 为例。关键在于其创建对象时的构造参数:
可以直接使用【文件输入字符流的对象】作为参数
也可以使用【文件输入字节流】通过【字节流转为字符流 的对象】作为参数
转换流简介
InputStreamReader OutputStreamWriter
转换流用于把【字节流转为字符流】
代码示例(下列代码演示了缓冲流+转换流的搭配使用)
- package com.zhan02;
-
- import java.io.*;
-
- public class BufferedWriterTest {
- public static void main(String[] args) throws IOException {
-
- FileOutputStream fileOutputStream = new FileOutputStream("working.txt",true);
- //通过创建转换流对象,利用【文件输出字节流对象】创建了【文件输出字符流对象】
- OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
-
- //构造参数内部传入的是FileOutputStream的对象,表示属于FileOutputStream的缓冲
- BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
- //这样写也行,相当于直接传入一个【文件字符输出流】给【文件缓冲字符输出流】作为创建对象的构造函数的参数
- //BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(String path));
-
- bufferedWriter.write("追加成功!");
- bufferedWriter.flush();
-
- bufferedWriter.close();
-
- }
- }
FileOnputStream类用来指向working.txt文本,构造方法里的true表示当进行写入是以追加形式写入
OutputSteamWriter用于从字节流转换到字符流
BufferWriter就是属于字符型的缓冲流
数据流简介
DataInputStream(字节流) DataOutputStream(字节流)
作用:
可以将数据的类型如 num 是int型一并写入文件。(但是该文件不是文本文件,使用记事本打开是乱码的,有效保证了安全性)
保障数据安全性:输出的文件很可能为乱码,只有通过数据流方式读取时才能解码
因为输入时是按顺序输入的,所以读取时也需要按顺序读取,否则会报错
代码示例
- public static void main(String[] args) {
- DataOutputStream dos = null;
- DataInputStream dis = null;
- try {
- //创建写出,读入流文件,构造器中放入节点流对象.
- dos = new DataOutputStream(new FileOutputStream("Test.txt"));
- dis = new DataInputStream(new FileInputStream("Test.txt"));
-
- dos.writeInt(20);
- dos.writeUTF("Tom");
- dos.writeChar('M');
-
- System.out.println(dis.readInt());
- System.out.println(dis.readUTF());
- System.out.println(dis.readChar());
-
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
-
- if (dos != null) {
- try {
- dos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- if (dis != null){
- try {
- dis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- }
- }
标准输出流简介
PrintStream(字节流) PrintWriter(字符流)
作用:FileInputStream是标准输入流,相对的,标准输出流却不是FileOutputStream而是PrintStream
标准输出流不需要手动 close( )关闭
如:PrintStream ps = System.out; ps.println("System本身就是一个标准输出流,其输出终点是控制台")
通过PrintStream输出内容到文件
- PrintStream ps=new PrintStream("mydir\\ps.txt");
- ps.write(97); //97写入ps.txt文件
通过PrintStream改变System.out的输出方向(默认是控制台,但是可以改变到文件中)
- PrintStream ps = new PrintStream("mydir\\ps.txt");
- System.setOut(ps); //改变System.out的输出方向(默认是控制台,但是可以改变到文件中)
- System.out.println(97); //97写入ps.txt文件
- System.setOut(System.out); //系统标准的输出流方向还可以改回控制台
- //不会自动flush
- PrintWriter pw=new PrintWriter("mydir\\java.txt");
- pw.write("hello");//要刷新
- pw.flush();
- pw.write("\r\n");//换行
-
- pw.println("hello");
- pw.flush();
-
- //自动flush
- PrintWriter pw=new PrintWriter("mydir\\java.txt",true);
- pw.write("hello");//要刷新
- pw.write("\r\n");//换行
利用标准输出流对象,结合System.setOut(new PrintStream)方法,改变System.out.println() 的输出方向,由默认的输出到控制台转变为输出到指定文件中。
如果要恢复System输出流指向控制台,则需要在最开始保存指向控制台的指针:PrintStream ps = System.out;
- public class PrintStreamClass {
- public static void main(String[] args) {
- try {
- log("第一次使用日志");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- public static void log(String message) throws FileNotFoundException {
- //保存当前指向控制台的指针
- PrintStream ps = System.out;
-
- //Step1.设置一个以FileOutputStream参数为构造方法的标准输出流PrintStream printstream
- String path = "log.txt";
- PrintStream printStream = new PrintStream(new FileOutputStream(path));
- System.setOut(printStream);
- //Step2.把printStream作为System.setOut的参数传递进来,改变输出方向为log.txt文本
- Date date = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
- String time = sdf.format(date);
- //Step3.获取当前的时间字符串,输出时间和信息 到文本文件log.txt中
- System.out.println(time+":"+message);
-
- //恢复System输出流的方向(需要使用原先保存的控制台指针)
- System.setOut(ps);
- System.out.println(22);
-
- }
- }