IO流概述
什么是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也会认为是同一个类