什么是IO
IO(Input Output):可以完成硬盘文件的读和写
输出表示内存到硬盘,叫写
输入表示硬盘到内存,叫读
IO流的分类
按照流的方向进行分类:
- 输出表示内存到硬盘,叫写
- 输入表示硬盘到内存,叫读
按照读取数据方式分类:
- 按字节方式读取数据,一次读一个字节,等同于一次读取8个进制位,这种流是万能的
读取:a中国
第一次读:一个字节,读到'a'
第二次读:一个字节,读到‘中’的一半
第三次读:一个字节,读到‘中’的另一半 - 按字符方式读取数据:一次读取一个字符,这种流是为了读取文本文件,不能读取图片 声音 视频,World也不行
读取:a中国
第一次读:一个字符,读到'a'
第二次读:一个字符,读到‘中’
综上所述
流的方向进行分类分为:输入流、输出流
按照读取数据方式分类:字符流、字节流
IO的四大家族
java.io.InputStream字节输入流
java.io.OutputStream字节输出流
java.io.Reader字符输入流
java.io.Writer字符输出流
以Stream结尾都是字节流,以Reader/Writer结尾都是字符流,所有流都实现了关闭接口,都是可关闭的。
所有的输出流都是可刷新的都有flush方法(),使用输出之后记得刷新使用,刷新是用来将中剩余数据强行输出完,清空管道。
Java.IO包下需要掌握的流有16个
文件专属:
java.io.FileInputStream java.io.FileOutputStream java.io.FileReader java.io.FileWriter
转换流专属(字节流转换为字符流):
java.io.InputStreamReader java.io.OutputStreamWriter
缓冲流专属:
java.io.BufferedReader java.io.BufferedWriter java.io.BufferedInputStream java.io.BufferedOutputStream
数据流专属:
java.io.DataInputStream java.io.DataOutputStream
标准输出流:
java.io.PrintStream java.io.PrintWriter
对象专属流:
java.io.objectInputStream java.io.ObjectOutputStream
FileInputStream
package com.java.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamText { public static void main(String[] args) throws IOException { FileInputStream fileInputStream=null; try { fileInputStream=new FileInputStream("D:\\批量网页\\q.txt"); byte[] bytes=new byte[1024]; int readcount= 0; while ((readcount=fileInputStream.read(bytes))!=-1)//判断是否读完 { System.out.println(new String(bytes,0,readcount)); } } catch (IOException e) { e.printStackTrace(); } finally { if(fileInputStream!=null) { fileInputStream.close(); } } } }
FileOutputStream
package com.java.io; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamText { public static void main(String[] args) throws IOException { FileOutputStream fileOutputStream=null; fileOutputStream=new FileOutputStream("myfile");//没有文件就对自动新建 有内容会先清空 其他构造方法可以追加写入 byte[] bytes ={97,98,99,100}; String name="我是中国人"; name.getBytes();//可以把字符串转化成字节数组 fileOutputStream.write(bytes);//写入 fileOutputStream.flush();//刷新 fileOutputStream.close(); } }
FileInputStream和FileOutputStream实现文件Copy
package com.java.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileCopy { public static void main(String[] args) throws IOException { FileOutputStream fileOutputStream=null; FileInputStream fileInputStream=null; fileInputStream=new FileInputStream("D:\\批量网页\\image0.png"); fileOutputStream=new FileOutputStream("D:\\image0.png"); byte[] bytes=new byte[1024];//1kb 一边读一边写 int readcount=0; while ((readcount=fileInputStream.read(bytes))!=-1) { fileOutputStream.write(bytes,0,readcount);//读多少写多少 } fileOutputStream.flush();//输出之后刷新 fileInputStream.close(); fileOutputStream.close(); } }
FileReader字符输入流
专门读取字符流,只能读普通文本
package com.java.io; import java.io.FileReader; import java.io.IOException; public class FileReaderText { public static void main(String[] args) throws IOException { FileReader reader=null; reader=new FileReader("myfile"); char[] chars=new char[4];//一次读取四个字符 int count=0; while (( count=reader.read(chars))!=-1) { System.out.println(new String(chars,0,count)); } } }
FileWrite字符输出流
package com.java.io; import java.io.FileWriter; import java.io.IOException; public class FileWriteText { public static void main(String[] args) throws IOException { FileWriter write=null; write=new FileWriter("files"); char[] chars={'中','国','人'}; write.write(chars); write.flush(); if(write!=null) { write.close(); } } }
BufferedReader带有缓冲的字符输入流
package com.java.io; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class BufferedReaderText { public static void main(String[] args) throws IOException { FileReader fileReader=new FileReader("myfile"); BufferedReader bufferedReader=new BufferedReader(fileReader); //这个程序fileReader就是一个节点,BufferedReader包装流/处理流 //不需要指定 byte数组,不需要指定char数组 //BufferedReader中调用的是子类Reader类的方法 String line= null; while ((line=bufferedReader.readLine())!=null)//一次读一行 { System.out.println(line); } } }
InputStreamReader转换流
package com.java.io; import java.io.*; public class InputStreamReaderText { public static void main(String[] args) throws IOException { //字节输入流 FileInputStream fileInputStream=new FileInputStream("myfile"); //包装流 把字节输入流转换成字符输入流 InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream); //包装流 把字符输入流转换成字符缓冲输入流 BufferedReader bufferedReader=new BufferedReader(inputStreamReader); String line=null; while ((line=bufferedReader.readLine())!=null) { System.out.println(line); } } }
DataInputStream数组专属输入流
package com.java.io; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class DataInputStreamText { public static void main(String[] args) throws IOException { DataOutputStream dataOutputStream=new DataOutputStream(new FileOutputStream("data")); byte b=100; short s=200; int i=300; long l=100L; float f=1.0F; dataOutputStream.writeByte(b); dataOutputStream.writeShort(s); dataOutputStream.write(i); dataOutputStream.writeLong(l); dataOutputStream.writeFloat(f); dataOutputStream.close(); } }
只有通过DataInputStream才能将其中的数据读取出来,还得直到加密规则,按什么顺序写就只能按什么顺序读。
PrintStream标准输出流
package com.java.io; import java.io.*; public class PrintStreamText { public static void main(String[] args) throws FileNotFoundException { System.out.println("hello world"); //相当于上面代码 PrintStream ps=System.out; ps.print("hello zhangsan"); ps.print("hello lisi"); //标准流不再指向日志文件 指向“log”文件 日志框架实现原理 PrintStream printStream=new PrintStream(new FileOutputStream("files")); System.setOut(printStream); System.out.println("2021-4-14"); } }
File文件目录
package com.java.io; import java.io.File; import java.io.IOException; public class FileText { public static void main(String[] args) throws IOException { File file=new File("Textfile"); if(!file.exists())//如果路径不存在 以文件方式创建 { file.createNewFile();//以文件方式创建 file.mkdir();//以目录方式创建 String path=file.getParent();//获取父路径 file.getAbsoluteFile();//获取绝对路径文件 file.getAbsolutePath();//获取绝对路径 file.isDirectory();//判断是否是目录 file.isFile();//是否是文件 file.lastModified();//获取文件最后一次修改时间 1970-now毫秒数 file.length();//获取文件大小 File[] files=file.listFiles();//返回所有文件目录 } } }
ObjectOutputStream序列化
序列化和反序列化:
序列化:Serialize java对象存储到文件中,将java对象的状态保存下来的过程
反序列化:Deserialize 将硬盘上的数据重新恢复到内存中,恢复成java对象
package com.java.io; import java.io.*; public class objectInputStreamText { public static void main(String[] args) throws IOException { //创建java对象 Student student=new Student("yy",22); //序列化 ObjectOutputStream objectInputStream=new ObjectOutputStream(new FileOutputStream("student")); //序列化对象 objectInputStream.writeObject(student); objectInputStream.flush(); objectInputStream.close(); } //Serializable是标志接口 里面没什么内容 JVM该标识看到之后会自动提供序列化版本号 public static class Student implements Serializable { public String name; public int age; public Student(String name,int age) { this.name=name; this.age=age; } public int getAge() { return age; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } @Override public String toString() { return "name:"+name+",age:"+age; } } }
序列化版本号的作用
但是后续不能修改代码,后续跟改了类,就不能反序列化。
解决办法:手动新建一个序列号版本,保持唯一不变就可以了,以后即使修改了,JVM也会认为是同一个类