今天学习IO流的相关知识。
File类 在程序中抽象的表示计算机中的文件或目录。 一个File类对象可以表示文件和路径, 可以对文件的属性进行操作,但不能直接对文件进行读写操作。
路径有两种:
绝对路径,完整的路径 D:\File.txt
相对路径,不是全路径,是两个文件的相对同一个父级的路径 File.txt
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class Demo1 {
/*
File类
在程序中抽象的表示计算机中的文件或目录。
一个File类对象可以表示文件和路径,
可以对文件的属性进行操作,但不能直接对文件进行读写操作
路径有两种:
绝对路径,完整的路径 D:\File.txt
相对路径,不是全路径,是两个文件的相对同一个父级的路径 File.txt
*/
public static void main(String[] args) {
File f1=new File("D:\\File.txt");//File类的构造方法
String s="D:\\";
new File(s,"File1.txt");
new File(s,"File2.txt");
new File(s,"File3.txt");
File f2=new File("D:\\Files");
if (!f2.exists()) {
f2.mkdir();//创建一级目录(文件夹)
}
f2.delete();//删除目录时,目录要为空
File f3=new File("D:\\File1\\File2\\File3");
if (!f3.exists()) {
f3.mkdirs();//创建多级目录
}
f3.delete();
if (!f1.exists()){//判断文件是否存在
try {
f1.createNewFile();//新建一个文件
} catch (IOException e) {
e.printStackTrace();
System.out.println("路径不正确");
}
}
System.out.println(f1.canRead());//判断文件是否可读
System.out.println(f1.canWrite());//判断文件是否可写
System.out.println(f1.getAbsoluteFile());//获取文件的绝对地址
System.out.println(f1.getParent());//返回路径名的父
System.out.println(f1.length());//获取文件的长度(字节数,以字节为单位)
System.out.println(new Date(f1.lastModified()));//获取文件的最后修改时间
System.out.println(f1.delete());//删除文件
System.out.println(f1.isFile());//判断是否为路径
System.out.println(f1.isDirectory());//判断是否为目录
}
}
对目录遍历,获得所有子目录和文件
import java.io.File;
import java.io.FileFilter;
public class Demo3 {
/*
对目录遍历,获得所有子目录和文件
*/
public static void main(String[] args) {
//对目录里的文件进行遍历,获得某个目录中的所有子目录或文件的文件名,以String返回
File f1=new File("C:/JAVA 非凡");
String[] strings=f1.list();
for (String s:strings){
System.out.println(s);
}
//对目录里的文件进行遍历,获得某个目录中的所有子目录或文件,以File对象返回
File f2=new File("C:/JAVA 非凡");
File [] files=f2.listFiles();
for (File s:files) {
System.out.println(s);
}
//设置条件来选择要操作的对象,返回File对象
File f3 = new File("C:/JAVA 非凡");
File[] files1=f3.listFiles(new MyFileFilter());
for (File s:files1){
System.out.println(s);
}
}
}
import java.io.File;
import java.io.FilenameFilter;
public class MyFileFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("java");
}
}
输入输出,将电脑的硬盘上的数据往程序读为输入,把程序中的数据往程序外读为输出。
IO流中的流意思是读写文件的操作类。
IO输入流和输出流,读写文件的操作,根据操作单位不同可分为:
1.字节流以字节为单位,读取时,每次读一个字节
InputStream 字节流输出
OutputStream 字节流输入
2.字符流 以子符为单位,读取时,每次读一个字符,只适合读文本文件
Reader read 字符流输出
Writer writer 字符流输入
import java.io.*;
public class Demo2 {
/*
IO输入流和输出流
读写文件的操作
根据操作单位不同可分为:
1.字节流
以字节为单位,读取时,每次读一个字节
InputStream 字节流输出
OutputStream 字节流输入
2.字符流
以子符为单位,读取时,每次读一个字符
只适合读文本文件
Reader read 字符流输出
Writer writer 字符流输入
*/
public static void main(String[] args) throws IOException {
File file=new File("D:/File.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件已存在");
}
FileInputStream in=new FileInputStream(file);
FileOutputStream out=new FileOutputStream("D:/File2.txt");
//字节流输出
int n=0;
while ((n=in.read())!=-1){
System.out.println(n);
}
in.close();//关闭流的通道,释放对文件的占用
//字节流输入
int t=0;
while ((t=in.read())!=-1){
out.write(t);
}
out.close();//关闭流的通道,释放对文件的占用
}
}
字节流的输入输出使用InputStream和OutputStream两种方法。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4 {
/*
字节流
*/
public static void main(String[] args) throws IOException {
FileInputStream in=null;
FileOutputStream out=null;
try {
in =new FileInputStream("D:\\File.txt");
out =new FileOutputStream("D:\\File1.txt");
int n=0;
while ((n=in.read())!=-1){
//in.read();//读取时以int字节形式读取,一次读取一个字节,当文件读完时返回-1
out.write(n);//写入时,一次向目标写入一个字节
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(e.getMessage());//日志记录
}finally {
if (in!=null)
in.close();//关闭流的通道,释放对文件的占用
if (out!=null)
out.close();//关闭流的通道,释放对文件的占用
}
byte[] bytes=new byte[10];
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo5 {
public static void main(String[] args) throws IOException {
FileInputStream in=null;
FileOutputStream out=null;
try {
in =new FileInputStream("D:\\File.txt");
out =new FileOutputStream("D:\\File1.txt");
//这每次读一个字节,时间长
// int n=0;
// while ((n=in.read())!=-1){
// out.write(n);//写入时,一次向目标写入一个字节
// }
//这根据定义的byte数组长度,每次读byte.length个字节
//当最后一次剩余字节不足以将byte数组放满,则剩多少放多少
byte[] bytes=new byte[5];
int size=0;
while ((size=in.read(bytes))!=-1){
System.out.println("这次byte中放入字节数为:"+size);
//in.read();//读取时以int字节形式读取,一次读取一个字节,当文件读完时返回-1
out.write(bytes,0,size);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(e.getMessage());//日志记录
}finally {
if (in!=null)
in.close();//关闭流的通道,释放对文件的占用
if (out!=null)
out.close();//关闭流的通道,释放对文件的占用
}
}
}
根据封装的类型,流可分为字节流和处理流。
节点流 流对象是直接对数据进行操作。 例如:构造方法(文件)
处理流(包装流) 流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);
节点流中的常用类:
字节输入流 FileInputStream
字节输出流 FileOutputStream
字符输入流 FileReader
字符输出流 FileWriter
import java.io.*;
public class Demo7 {
/*
节点流
流对象是直接对数据进行操作。 例如:构造方法(文件)
处理流(包装流)
流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);
*/
public static void main(String[] args) throws IOException {
FileInputStream in=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.exe");
FileOutputStream out= new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.txt");
BufferedInputStream bin = new BufferedInputStream(in);//缓存大小为DEFAULT_BUFFER_SIZE = 8192
BufferedOutputStream bout =new BufferedOutputStream(out);
int name=0;
while ((name=bin.read())!=-1){//将数据读入底层的数组中(缓存区中),待读满缓存区中的8192个再输出
bout.write(name);//并不是每次write都向磁盘去写数据,而是等缓存区数组满后再向磁盘输出
}
bin.close();
bout.flush();//操作完成后,将缓存区刷新清空
in.close();
out.close();
}
}
处理流中的常用类:
缓冲字节输出流 BufferedOutputStream
缓冲字节输入流 BufferedInputStream
缓冲字符输入流 BufferedReader
缓冲字符输出流 BufferedWriter
缓冲的输入流和输出流:
将数据读入底层的数组中(缓存区中,缓存大小为DEFAULT_BUFFER_SIZE = 8192),待读满缓存区中的8192个再输出;并不是每次write都向磁盘去写数据,而是等缓存区数组满后再向磁盘输出。
import java.io.*;
public class Demo6 {
/*
节点流
流对象是直接对数据进行操作。 例如:构造方法(文件)
处理流(包装流)
流对象中包装的是另一个流,提供一些额外的数据处理。 例如:ObjectInputStream(InputStream in);
*/
public static void main(String[] args) throws IOException {
FileInputStream in=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.exe");
FileOutputStream out= new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\feige.txt");
BufferedInputStream bin = new BufferedInputStream(in);//缓存大小为DEFAULT_BUFFER_SIZE = 8192
//BufferedInputStream bin = new BufferedInputStream(in,1024);可改变缓存大小
BufferedOutputStream bout =new BufferedOutputStream(out);
byte[] bytes=new byte[1024*1024];//当自定义数组大于缓存区数组长度时,缓存区数组会失效
int name=0;
while ((name=bin.read(bytes))!=-1){//将1024个数据读入byte数组中,再读入底层的数组中(缓存区中),待读满缓存区中的8192个再输出
System.out.println(bytes);
bout.write(name);
}
bin.close();
bout.flush();//操作完成后,将缓存区刷新清空
in.close();
out.close();
}
}
字符流
字符输入流的基类:Reader
子类:FileReader extends InputStreamReader(转换流,将读到的字节按编码表(charsset)转换为字符)
字符输出流的基类:Writer extends OutputStream
子类:FileWriter extends InputStreamWriter(转换流,将读到的字符按编码表(charsset)转换为字节写出)
汉子的输入输出问题:
在uft-8编码表中,一个汉子等于三个字节,底层存储的单位是字节,通过转换流,将读到的字节按编码表(charsset)转换为字符。
import java.io.*;
public class Demo8 {
/*
字符流
字符输入流的基类:Reader
子类:FileReader extends InputStreamReader(转换流,将读到的字节按编码表(charsset)转换为字符)
字符输出流的基类:Writer extends OutputStream
子类:FileWriter extends InputStreamWriter(转换流,将读到的字符按编码表(charsset)转换为字节写出)
汉子的输入输出问题:在uft-8编码表中,一个汉子等于三个字节,底层存储的单位是字节,通过转换流,将读到的字节按编码表(charsset)转换为字符。
缓冲输入:BufferedReader
缓冲输出:BufferedWriter
*/
public static void main(String[] args) throws IOException {
FileReader fileReader=new FileReader("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File1.txt");
FileWriter fileWriter=new FileWriter("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File2.txt");
// int name;
// while ((name= fileReader.read())!=-1){
// fileWriter.write(name);
// }
char[] chars=new char[5];
int name;
while ((name= fileReader.read(chars))!=-1){
fileWriter.write(chars,0,name);
}
fileReader.close();
fileWriter.close();
}
}
字符流缓冲输入:BufferedReader
字符流缓冲输出:BufferedWriter
import java.io.*;
public class Demo9 {
/*
字符流
缓冲输入:BufferedReader
缓冲输出:BufferedWriter
*/
public static void main(String[] args) throws IOException {
FileReader fileReader=new FileReader("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File1.txt");
FileWriter fileWriter=new FileWriter("C:\\Users\\Nexus\\Desktop\\2022-7-11_java第八章IO\\练习\\File2.txt");
//FileWriter fileWriter=new FileWriter(fileName,true);写入数据时,可以保留之前的数据,追加内容
BufferedReader bufferedReader=new BufferedReader(fileReader);
BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);
// int name;
// while ((name= fileReader.read())!=-1){
// fileWriter.write(name);
// }
// char[] chars=new char[5];
// int name;
// while ((name= bufferedReader.read(chars))!=-1){
// //bufferedWriter.write(chars);
// bufferedWriter.write(chars,0,name);
// }
int name;
String line;
while ((line=bufferedReader.readLine())!=null){//readLine()一次可以读取一行数据
bufferedWriter.write(line);
bufferedWriter.newLine();//插入换行符
}
bufferedReader.close();
bufferedWriter.close();
fileReader.close();
fileWriter.close();
}
}
Print流(打印流):只做输出操作,单位的从程序向目标输出数据,没有输入操作。按打印的数据类型分可分为字节打印流和字符打印流。
PrintWriter:字符打印流print方法可以打印各种数据类型的数据。
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class Demo10 {
/*
Print流
打印流:只做输出操作,单位的从程序向目标输出数据,没有输入操作。按打印的数据类型分可分为字节打印流和字符打印流。
PrintWriter
字符打印流print方法可以打印各种数据类型的数据
*/
public static void main(String[] args) throws FileNotFoundException {
PrintWriter printWriter=new PrintWriter("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\test.html");
printWriter.print("Hello world");
printWriter.print("Hello world");
printWriter.print("Hello world");
printWriter.print("Hello world");
printWriter.close();
}
}
在编码过程中,对象被存储在内存中,程序终止运行时,内存数据会被刷新清空,有时需要保存对象中的数据,需要使用流对象,将对象数据输出到文件中,做到对象数据的持久化(长久保存)。
对象输入输出流,都属于处理流:
ObjectInputStream(反序列化) ObjectOutputStream(序列化)
这过程也称为对象序列化和反序列化。
import java.io.*;
import java.util.Date;
public class Demo11 {
/*
在编码过程中,对象被存储在内存中,程序终止运行时,内存数据会被刷新清空
有事需要保存对象中的数据,需要使用流对象,将对象数据输出到文件中,做到对象数据的持久化(长久保存)
对象输入输出流,都属于处理流:
ObjectInputStream(反序列化)
ObjectOutputStream(序列化)
这过程也称为对象序列化和反序列化.
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
//对象序列化,对象序列化后有它自己特定的格式
FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
Date date=new Date();
String s="ABCdef";
objectOutputStream.writeObject(date);
objectOutputStream.writeObject(s);
objectOutputStream.flush();
objectOutputStream.close();
//对象反序列化,会新创建对象
FileInputStream fileInputStream=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
Date date1=(Date) objectInputStream.readObject();
String s1=(String)objectInputStream.readObject();
System.out.println(date1);
System.out.println(s1);
objectInputStream.close();
}
}
Serializable 序列化接口:如果需要将某一对象进行序列化,那么此类必须实现Serializable接口 实现后,会生成一个版本号,如果不显示的定义版本号,会自定默认生成。
对象序列化,对象序列化后有它自己特定的格式;对象反序列化,会新创建对象。
自动生成版本号会有一个问题,每次当类改变了,版本号会重新生成 所以但一个类需要经常序列化和反序列化时,建议显式定义版本号。
序列化版本号,版本号的显式定义后,类信息发生改变后不会重新生成。
transient关键字:transient定义的属性,在序列化时不会保存到文件中。
import java.io.Serializable;
public class Animal implements Serializable {
/*
Serializable 序列化接口
如果需要将某一对象进行序列化,那么此类必须实现Serializable接口
实现后,会生成一个版本号,如果不显示的定义版本号,会自定默认生成,
自动生成版本号会有一个问题,每次当类改变了,版本号会重新生成
所以但一个类需要经常序列化和反序列化时,建议显式定义版本号
*/
//序列化版本号,版本号的显式定义后,类信息发生改变后不会重新生成
private static final long serialVersionUID = -5869686875672962881L;
//transient定义的属性,在序列化时不会保存到文件中
private transient int age;
private String name;
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
import java.io.*;
import java.util.Date;
public class AnimalTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//对象序列化,对象序列化后有它自己特定的格式
FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
Animal animal1=new Animal(5,"旺财");
objectOutputStream.writeObject(animal1);
objectOutputStream.flush();
objectOutputStream.close();
//对象反序列化,会新创建对象
FileInputStream fileInputStream=new FileInputStream("C:\\Users\\Nexus\\Desktop\\2022-7-12_java第八章IO\\练习\\temp\\test.txt");
ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
Animal animal2=(Animal) objectInputStream.readObject();
System.out.println(animal2);
objectInputStream.close();
}
}