文章目录
IO流
一.File类
1.详述
-
File类是java.io包中很重要的一个类;
-
File类的对象可以表示文件,还可以表示目录,在程序中一个File类对象可以代 表一个文件或目录(文件夹);
-
File对象可以对文件或目录的属性进行操作,如:文件名、最后修改日期、文件 大小等;
-
可以读取文件属性,创建,删除文件/目录(文件夹)
-
File对象无法操作文件的具体数据,即不能直接对文件进行读/写操作
2.方法
1.构造方法
File(“E:/demo.txt”); 传进来一个绝对路径
File(parent, “demo.txt”); 传进来文件夹路径,再传入文件名称
代码示例
File file = new File("E:/demo.txt");
System.out.println(file.isFile());
String parent = "E:/";
File file1 = new File(parent, "demo.txt");
System.out.println(file1.isFile());
File file2 = new File(parent, "demo.txt");
2.常用方法
代码
public class FileDemo1 {
public static void main(String[] args) {
File file1=new File("D:/demo.doc");
File file2=new File("D:/","demo.doc");
File file3=new File("D:/javaSE");
System.out.println(file2.canExecute()); //文件
System.out.println(file2.canRead()); //文件是否能写
System.out.println(file2.canWrite()); //文件是否能读
System.out.println(file2.exists()); //文件是否存在
System.out.println(file2.isFile()); //判断是否为文件为文件
System.out.println(file2.isDirectory()); //判断是否为文件夹
System.out.println(file2.isAbsolute()); //判断是否为绝对路径
System.out.println(file3.list());
}
}
public class FileDemo2 {
public static void main(String[] args) {
File file = new File("E:/demo1.txt");
/*if(!file.exists()){
try {
file.createNewFile();//创建文件
} catch (IOException e) {
e.printStackTrace();
}
}*/
//file.delete(); 删除文件
//File file1 = new File("E:/demo");
//file1.mkdir(); //只能创建单级目录
//file1.mkdirs();//可以创建多级目录
//file1.delete();//删除文件夹时,一次只能删除一级且文件夹为空
File file1 = new File("E:/api");
/* String [] fileNames = file1.list();//获得当前目录下的所有文件名和目录名(以字符串形式返回)
for(String s : fileNames){
System.out.println(s);
}*/
/* File[] files = file1.listFiles();//获得当前目录下的所有文件名和目录名(返回的是文件对象)
for(File f : files){
System.out.println(f.isFile());
}*/
//文件过滤
File[] files = file1.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith("chm");//自定义的文件过滤条件
}
});
for(File f : files){
System.out.println(f);
}
}
}
2.输入及输出的概念
(1)输入输出(I/O)
把电脑硬盘上的数据读到程序中,称为输入,即input,进行数据的read 操作(I)
从程序往外部设备写数据,称为输出,即output,进行数据的write(O)
二.字节流字符流
从数据流编码格式上划分为 字节流 字符流
字节流字符流体系框架图
1.输入流与输出流
流按着数据的传输方向分为:
输入流:从电脑硬盘(外界)往程序中读叫输入流。
输出流:从程序中往外写叫输出流。
- InputStream和OutputStream的子类都是字节流 可以读写二进制文件,主要处理音频、图片、歌曲、字节流,处理单元为1个字节。
- Reader和Writer的子类都是字符流 主要处理字符或字符串,字符流处理单元为1个字符。 字节流将读取到的字节数据,去指定的编码表中获取对应文字。
字节流
输入流
InputStream的基本方法
-
int read() throws IOException 读取一个字节并以整数的形式返回(0~255),如果返回-1已到输入流的末尾。
-
int read(byte[] buffer) throws IOException 读取一系列字节并存储到一个数组byte[], 返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
-
void close() throws IOException 关闭流释放内存资源
输出流
OutputStream的基本方法
-
void write(int b) throws IOException 向输出流中写入一个字节数据,该字节数据为参数b的低8位
-
void write(byte[] b, int off, int len) throws IOException 将一个字节类型的数组中的从指定位置(off)开始的 len个字节写入到输出流
-
void close() throws IOException 关闭流释放内存资源
字节流中常用类
字节输入流 FileInputStream
字节输出流 FileOutputStream
代码示例
import java.io.*;
public class StreamDemo1 {
public static void main(String[] args) throws IOException {
//首先我们要告诉java输入流,去读取计算机上的哪个文件
File f = new File("E:/demo.txt");
FileInputStream in = new FileInputStream(f);
//System.out.println(in.read()); //从文件中每read一次就输入一个字节
//告诉java输出流,输出到哪个文件
FileOutputStream out = new FileOutputStream("F:/demo.txt");
//循环读写
for(int i=0;i<f.length();i++) {
out.write(in.read());
}
//关闭流通过,解除文件占用
in.close();
out.close();
}
}
public class StreamDemo2 {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
//首先我们要告诉java输入流,去读取计算机上的哪个文件
in = new FileInputStream("E:/demo.txt");
//告诉java输出流,将文件输出到哪个目标文件中,会自动创建输出文件
out = new FileOutputStream("F:/demo.txt");
//in.read();//每次读取一个字节并返回,当文件内容读完之后,会返回一个-1
int b = 0;//读到结果
while((b=in.read())!=-1){
out.write(b);//一次向外输出(写)一个字节
}
}catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件找不到");
}catch (IOException io){
io.printStackTrace();
System.out.println("读写异常");
}finally{
try {
if(in!=null){
in.close();//关闭流的通道,释放文件占用
}
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class StreamDemo3 {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("E:/demo.txt");
out = new FileOutputStream("F:/demo.txt");
//in.read(); 每次只读一个字节并返回,读完返回-1 效率低
byte[] b = new byte[1024];//7 266
int length = 0;
//read(byte[] b)每次最多读byte数组长度个字节,返回数组中实际装入的字节个数 266,读完返回-1
while((length= in.read(b))!=-1){
//每次向外写一个byte个字节,从指定位置开始(一般情况从0开始),向外写length个长度
out.write(b,0,length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException io){
io.printStackTrace();
}finally {
try {
if(in!=null){
in.close();
}
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流
输入流
Reader 的基本方法
-
int read() throws IOException 读取一个字符并以整数的形式返回, 如果返回-1已到输入流的末尾。
-
int read( char[] cbuf) throws IOException 读取一系列字符并存储到一个数组buffer, 返回实际读取的字符数,如果读取前已到输入流的末尾返回-1
-
void close() throws IOException 关闭
输出流
Writer 的基本方法
-
void write(int c) throws IOException 向输出流中写入一个字符数据,该字节数据为参数b的16位
-
void write( char[] cbuf) throws IOException 一个字符类型的数组中的数据写入输出流,
-
void write( char[] cbuf, int off set, int length) throws IOException 将一个字符类型的数组中的从指定位置(off set)开始的 length个字符写入到输出流
-
void close() throws IOException 关闭
字符流中常用类
字符输入流 FileReader
字符输出流 FileWriter
代码示例
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharDemo1 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("E:/1.jpg");
FileWriter fileWriter = new FileWriter("F:/1.jpg");
int c = 0;
while ((c=fileReader.read())!=-1){
fileWriter.write(c);
}
fileReader.close();
fileWriter.close();
}
}
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharDemo2 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("E:/demo.txt");
FileWriter fileWriter = new FileWriter("F:/demo.txt");
char [] c = new char[5];
int length = 0;
while((length=fileReader.read(c))!=-1){
fileWriter.write(c,0, length);
}
fileReader.close();
fileWriter.close();
}
}
三:节点流与处理流
1.处理流分析图解
处理流的使用可以让传输效率更高
2.字节节点流与处理流
字节输入流 FileInputStream (节点流)
字节输出流 FileOutputStream(节点流)
缓冲字节输出流 BufferedOutputStream (处理流)
缓冲字节输入流 BufferedInputStream (处理流)
代码示例
处理流的应用
import java.io.*;
public class BufferdStreamDemo {
public static void main(String[] args) {
try {
//原始低端的管道
FileInputStream in = new FileInputStream("E:/demo.txt");
//用带缓冲区的高级管道包装一下
BufferedInputStream bin = new BufferedInputStream(in,2048);
FileOutputStream out = new FileOutputStream("F:/demo.txt");
BufferedOutputStream bout = new BufferedOutputStream(out,2048);
byte[] b = new byte[1024];
int length = 0;
while((length=bin.read(b))!=-1){
bout.write(b,0,length);
}
bin.close();
bout.flush();//刷新缓冲区
bout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException io) {
io.printStackTrace();
}
}
}
节点流与处理流速率的比较
import javax.imageio.IIOException;
import java.io.*;
public class two {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
long a = 0;
try {
a = System.currentTimeMillis();
in = new FileInputStream("D:/考虫/四级词汇/四级词汇84.mp4");
out = new FileOutputStream("D:/la.exe");
/*
byte[] b = new byte[1024]; //节点流
int lenght = 0;
while ((lenght = in.read(b)) != -1) {
out.write(b, 0, lenght);
}*/
BufferedInputStream bin=new BufferedInputStream(in); //处理流
BufferedOutputStream bout=new BufferedOutputStream(out);
byte[] b=new byte[1024];
int lenght=0;
while ((lenght = bin.read(b)) != -1) {
bout.write(b, 0, lenght);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
System.out.println("读写错误");
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("节点流的处理效率为:" + (System.currentTimeMillis() - a)); //节点流的处理时间为290毫秒
System.out.println("处理流的处理效率为:" + (System.currentTimeMillis() - a)); //处理流的处理时间为70毫秒
}
}
3.字符节点流与处理流
字符输入流 FileReader (节点流)
字符输出流 FileWriter (节点流)
缓冲字符输入流 BufferedReader (处理流)
缓冲字符输出流 BufferedWriter(处理流)
代码示例
处理流的应用
import java.io.*;
public class CharDemo3 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("E:/demo.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
FileWriter fileWriter = new FileWriter("F:/demo.txt",true); //设置构造方法中参数append的值为true数据就可以叠加了
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
String line = null; //一次读入一行数据
while((line=bufferedReader.readLine())!=null){
bufferedWriter.write(line);//一次写出一行数据
bufferedWriter.newLine();//换行
}
bufferedReader.close();
bufferedWriter.close();
}
}
注:
创建输出流对象时输出流的构造方法的append参数值设置为ture值数据就可以叠加了
四.打印流
Print 打印流:只做输出没有输入
打印流分为字节打印流和字符打印流
PrintWriter:字符打印流
print方法可以打印各种类型数据
代码示例
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class PrintWriterDemo {
/*
打印流:只做输出,没有输入
从程序中向外输出(访问网页-->服务器就会将网页内容 以流的形式响应到浏览器)
*/
public static void main(String[] args) throws FileNotFoundException {
PrintWriter out = new PrintWriter("E:/index.html");
out.println("<h1>这是来自服务器的信息</h1>");
out.println("<h1>这是来自服务器的信息</h1>");
out.println("<h1>这是来自服务器的信息</h1>");
out.println("<h1>这是来自服务器的信息</h1>");
out.println("<h1>这是来自服务器的信息</h1>");
out.close();
}
}
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0J07nh8H-1636040184845)(C:\Users\封纪元\AppData\Roaming\Typora\typora-user-images\1624971101188.png)]
五.对象输入输出流(对象的序列化)
1.对象的输入输出流及对象序列化 :
主要的作用是用于写入对象信息与读取对象信息。 对象信息 一旦写到文件上那么对象的信息就可以做到持久化了
对象的输出流: ObjectOutputStream
ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。
对象的输入流: ObjectInputStream
在ObjectInputStream 中用readObject()方法可以直接读取一个对象
对象序列化:对象的输出流将指定的对象写入到文件的过程(将对象转换为字节),就是将对象序列化的过程,对象的输入流将指定序列化好的文件读出来的过程(将字节转换为对象),就是对象反序列化的过程。
实现对象序列化的要求:
实现 Serializable接口
Serializable接口中没有任何方法。当一个类声明实现Serializable接口后, 表明该类可被序列化。
在类中可以生成一个编号 private static final long serialVersionUID = -5974713180104013488L; 随机生成 唯一的
serialVersionUID 用来表明实现序列化类的不同版本间的兼容性。某个类在 与之对应的对象已经序列化出去后做了修改,该对象依然可以被正确反序列化
为何要实现Serializable接口,为何要生成一个唯一的id? 为了和其他包中重名的类区分
对象序列化要注意的问题:
1.如果需要将一个类的对象信息序列化到文件中时,此类需要生成一个序列化id号(版本号)implements Serializable接口 默认会在类中生成一个版本号,一旦类中的信息发生改变,版本号会自动变化 也可以显示的生成版本号,类的发生修改时,版本号不会改变
2.transient 在对象序列化时 忽略此属性
具体代码案例
需要对象序列化对象的类
import java.io.Serializable;
/*
如果需要将一个类的对象信息序列化到文件中时,此类需要生成一个序列化id号(版本号)
implements Serializable接口 默认会在类中生成一个版本号,一旦类中的信息发生改变,版本号会自动变化
也可以显示的生成版本号,类的发生修改时,版本号不会改变
*/
public class Student implements Serializable {
private static final long serialVersionUID = 7015935209947295264L;
private int num;
//transient 在对象序列化时 忽略此属性
private transient String name;
public Student(int num, String name) {
this.num = num;
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
}
对象序列化
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//案例:将程序运行时,那一刻的时间保存到文件中(直接将对象信息存起来---对象序列化)
/* Date date = new Date();
FileOutputStream out = new FileOutputStream("E:/object.txt");
ObjectOutputStream objectOut = new ObjectOutputStream(out);
objectOut.writeObject(date);
objectOut.close();*/
Student student1 = new Student(100,"张三1");
Student student2 = new Student(101,"张三2");
FileOutputStream out = new FileOutputStream("E:/object.txt");
ObjectOutputStream objectOut = new ObjectOutputStream(out);
objectOut.writeObject(student1);
objectOut.writeObject(student2);
objectOut.close();
}
}
对象反序列化
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/* FileInputStream in = new FileInputStream("E:/object.txt");
ObjectInputStream objectin = new ObjectInputStream(in);
Object obj = objectin.readObject();//将对象信息,从文件中输入到程序,这个过程称为反序列化
if(obj instanceof Date){//判断object中包含的是否是Date类型
Date date = (Date) obj;
System.out.println(date);
}*/
FileInputStream in = new FileInputStream("E:/object.txt");
ObjectInputStream objectin = new ObjectInputStream(in);
Student student1 = (Student) objectin.readObject();
Student student2 = (Student) objectin.readObject();
System.out.println(student1);
System.out.println(student2);
}
}