JavaSE-IO
File 类
File 可以帮助我们快速获取文件或者文件夹的属性等信息。
查找文件或者文件夹创建并删除。
File 类常用的方法
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class myFile01 {
public static void main(String[] args) throws IOException {
// 关联文件,直接传入地址,文件或者文件夹的路径
File file1 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\1.txt");
File filePath = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a");
File filePath2 = new File("C:\\Users\\Jming_er\\Desktop\\工具");
File file2 = new File("C:/Users/Jming_er/Desktop/工具/2.txt");
File file = new File("C:" + File.separator + "Users" + File.separator + "Jming_er" + File.separator + "Desktop" + File.separator + "工具" + File.separator + "1.txt");
/**
* API
* 比较:compareTo() equals()
* 创建:createNewFile() createTempFile() mkdir() mkdirs()
* 删除:delete()
* 判断:exists() isFile() isDirectory() isHidden() canExecute() canRead() canWrite()
* 查询:getAbsoluteFile() getAbsolutePath() getName() getParent() length()
*/
System.out.println("文件是否可执行:" + file.canExecute()); //true
System.out.println("文件是否可读:" + file.canRead()); //true
System.out.println("文件是否可写:" + file.canWrite()); //true
System.out.println("是否为文件" + file1.isFile()); //true
System.out.println("是否为目录" + file1.isDirectory()); //false
System.out.println("是否为隐藏" + file1.isHidden()); //false
// FileObject.compareTo(FileObject2) 字母顺序比较两个抽象类对象的路径,返回int 类型数据(hash码差值)
System.out.println(file2.createNewFile()); //如果文件不存在就创建,如果文件存在就不重复创建
System.out.println(file2.exists()); // 判断是否存在
System.out.println(file2.delete()); //删除文件
System.out.println(file1 == file); //false,比较地址
System.out.println(file1.equals(file)); //true,比较路径是否相等
File file3 = new File("a.txt");
System.out.println(file3.getAbsoluteFile());
System.out.println(file3.getAbsolutePath()); // 返回绝对路径
System.out.println(file3.getPath()); // 返回相对路径,相对于该项目下
System.out.println(file3); // 结果与getPath的结果是一样的
System.out.println("文件(带后缀)或文件夹名称" + file.getName()); //1.txt
System.out.println(file1.getParent()); // 获取上级目录路径
System.out.println(file1.getParentFile()); // 获取上级目录
System.out.println(file1.length()); //文件内容长度
/**
* 目录操作
*/
filePath.mkdir(); // 只能创建单层,且不存在时创建
filePath.mkdirs(); // 能创建多层,且不存在时创建
// filePath.delete(); // 只能删除空文件夹
String[] str = filePath2.list(); // 获取该目录下包含的文件或者文件夹
for (String s :
str) {
System.out.println(s);
}
System.out.println("-------------遍历文件---------------");
showFile(filePath2);
System.out.println("--------------递归遍历目录中的内容--------------");
showDetail(filePath, 1);
}
private static void showFile(File filePath2) {
File[] str2 = filePath2.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
});
for (int i = 0; i < str2.length; i++) {
System.out.println(str2[i]);
}
}
private static void showDetail(File filePath, int level) {
File[] str = filePath.listFiles(); // 获取某文件夹下的文件、文件夹的绝对路径
for (File file : str) {
for (int i = 0; i < level; i++) {
System.out.print("- ");
}
if (file.isDirectory()) {
System.out.println(file.getName());
showDetail(file, ++level);
} else
System.out.println(file.getName());
}
}
}
引入IO 流
1. IO 就是程序与数据源之间的桥梁
2. IO流的分类
输入流:源文件—>程序
输出流:程序—>目标位置
字节流
字符流
FileInputStream 类
- 获取文件内容
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class myFileInputStream {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
// IO 输入流
FileInputStream fileInputStream = new FileInputStream(file);
/**
* API
* 读取:read()
* 关闭流:close()
*/
int n = fileInputStream.read();
System.out.println(n); // 读取文件每个字节的ASCII 码(只能一次一次读)
fileInputStream.close();
}
}
发现read 方法一次只能读一个字节,所以进行循环。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class myFileInputStream {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
// IO 输入流
FileInputStream fileInputStream = new FileInputStream(file);
while(n!=-1){ // 读取全部内容的ASCII 码
System.out.println(n);
n = fileInputStream.read();
}
fileInputStream.close();
}
}
但是这样做如果文件内容比较大时效率就会低。
- 引入byte 缓冲数组,是的每次遍历数组长度的字节数,从而减少遍历次数。实际在开发中一般定义缓冲数组长度为1024的整数倍
byte[] bt = new byte[1024*4];
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class myFileInputStream {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
// IO 输入流
FileInputStream fileInputStream = new FileInputStream(file);
/**
* API
* 读取:read()
* 关闭流:close()
*/
int n = fileInputStream.read();
// 使用缓冲数组提高效率
byte[] bt = new byte[1024*6];
int n2 = fileInputStream.read(bt);
while(n2!=-1){ // 读取全部内容的ASCII 码
for (int i = 0; i <= n2-1; i++) {
System.out.println(bt[i]);
}
n2 = fileInputStream.read(bt);
}
fileInputStream.close();
}
}
FileOuputStream 类
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class myFileOutputStream {
public static void main(String[] args) throws IOException {
// 目标文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
// FileOutputStream fileOutputStream = new FileOutputStream(file,true);
FileOutputStream fileOutputStream = new FileOutputStream(file,false);
// 此处存在两个参数,默认(file,[append:false]),加上append 参数true 就可以进行写入的追加
/**
* API
* 写:write()
*/
fileOutputStream.write(97);// 结果发现文件不管存不存在都会写入内容在指定的文件中
fileOutputStream.write(98);// 如果没有append 参数,再一次执行会发生替换
// 直接间内容写入
String str = "这是写入内容";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
System.out.println(bytes.length);
fileOutputStream.write(bytes); // 3*6
fileOutputStream.close();
}
}
文件内容的复制
- 按照字节读取
import java.io.*;
public class myCopy {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
// 输入IO
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file2,true);
int n = fileInputStream.read();
while(n!=-1){
fileOutputStream.write(n);
n = fileInputStream.read();
}
fileOutputStream.close();
fileInputStream.close();
}
}
- 使用缓冲数组
import java.io.*;
public class myCopy {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
// 输入IO
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file2, true);
byte[] bt = new byte[8];
int n = fileInputStream.read(bt);
while (n != -1) {
System.out.println(n); // 8 8 3
fileOutputStream.write(bt);
n = fileInputStream.read(bt);
}
fileOutputStream.close();
fileInputStream.close();
}
}
查看结果:
源文件内容:abcd123456798你好
复制文件内容:abcd123456798你好98你
复制结果不相同:原因?
使用UTF-8,英文字符占1个字节,中文占3个字节。
解决方法,规定输出数组长度
import java.io.*;
public class myCopy {
public static void main(String[] args) throws IOException {
// 源文件
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
// 输入IO
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file2, true);
byte[] bt = new byte[8];
int len;
while ((len= fileInputStream.read(bt)) != -1) { // 读多少就输出多少
fileOutputStream.write(bt,0,n); // 将bt 数组的[0,n) 输出出来
}
fileOutputStream.close();
fileInputStream.close();
}
}
输出结果就是:
abcd123456798你好
其他复制方法
FileChannel 类(比较快)
public class Demo {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Jming_er\\Desktop\\javaStudy\\src\\com\\study\\a.text");
FileChannel channel = fileInputStream.getChannel();
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Jming_er\\Desktop\\javaStudy\\src\\com\\study\\b.text");
FileChannel channel1 = fileOutputStream.getChannel();
channel1.transferFrom(channel, 0, channel.size());
fileInputStream.close();
fileOutputStream.close();
}
}
第三方包Commons IO
Apache Commons IO提供拷贝文件方法在其FileUtils类,可用于复制一个文件到另一个地方。它非常方便使用Apache Commons FileUtils类时,您已经使用您的项目。基本上,这个类使用Java NIO FileChannel内部。 这是第三种方法的代码:
private static void copyFileUsingApacheCommonsIO(File source, File dest)throws IOException {
FileUtils.copyFile(source, dest);
}
该方法的核心代码如下:
private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
if (destFile.exists() && destFile.isDirectory()) {
throw new IOException("Destination '" + destFile + "' exists but is a directory");
}
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel input = null;
FileChannel output = null;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
input = fis.getChannel();
output = fos.getChannel();
long size = input.size();
long pos = 0;
long count = 0;
while (pos < size) {
count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos;
pos += output.transferFrom(input, pos, count);
}
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(fis);
}
if (srcFile.length() != destFile.length()) {
throw new IOException("Failed to copy full contents from '" +
srcFile + "' to '" + destFile + "'");
}
if (preserveFileDate) {
destFile.setLastModified(srcFile.lastModified());
}
}
由此可见,使用Apache Commons IO复制文件的原理就是上述第二种方法:使用FileChannel复制
使用Java7的Files类复制
private static void copyFileUsingJava7Files(File source, File dest)throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
参考:https://www.cnblogs.com/zq-boke/p/8523710.html
FileReader,FileWriter 字符流
字节输出与缓存机制说明
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class myFileReaderAndWriter {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
FileWriter fileWriter = new FileWriter(file2);
FileReader fileReader = new FileReader(file);
int data = fileReader.read();
while(data!=-1){
fileWriter.write(data);
data = fileReader.read();
}
// 注意:字节流既有缓存机制,如果不执行IO 流关闭无法输出结果(底层其实调用了flush()),但是可以调用flush() 将数据冲刷输出。
/*fileWriter.close();
fileReader.close();*/
fileWriter.flush(); // 冲刷输出
}
}
原理:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dqzgta3P-1653558994225)(imgclip.png “imgclip.png”)]
使用缓存字符数组进行复制
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class myFileReaderAndWriter {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
FileWriter fileWriter = new FileWriter(file2);
FileReader fileReader = new FileReader(file);
char[] chars = new char[8];
int data = fileReader.read(chars); // 传入的是字符数组
while (data != -1) {
fileWriter.write(chars, 0, data);
data = fileReader.read(chars);
}
// 注意:字节流既有缓存机制,如果不执行IO 流关闭无法输出结果(底层其实调用了flush()),但是可以调用flush() 将数据冲刷输出。
fileWriter.close();
fileReader.close();
}
}
BufferedReader,BufferedWriter 缓冲流
缓冲流依附在字节流上
import java.io.*;
public class myFileReaderAndWriter {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
FileWriter fileWriter = new FileWriter(file2);
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 通过读取缓冲字符数组进行复制
/*char[] chars = new char[8];
int data = bufferedReader.read(chars);
while (data != -1) {
bufferedWriter.write(chars, 0, data);
data = bufferedReader.read(chars);
}*/
// 通过字符串进行复制
String str = bufferedReader.readLine();
while(str!=null){
bufferedWriter.write(str);
bufferedWriter.newLine(); // 复制一行换一行
str = bufferedReader.readLine();
}
bufferedWriter.close();
bufferedReader.close();
}
}
try{}catch(e){}finally{} 模式
import java.io.*;
public class myFileReaderAndWriter {
public static void main(String[] args) {
File file = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt");
File file2 = new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt");
FileWriter fileWriter = null;
FileReader fileReader = null;
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter(file2);
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);
// 通过字符串进行复制
String str = bufferedReader.readLine();
while (str != null) {
bufferedWriter.write(str);
bufferedWriter.newLine(); // 复制一行换一行
str = bufferedReader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedWriter.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
System 类对IO的支持,转换流
import java.util.Scanner;
public class mySystemIO {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入数字:");
int num = scanner.nextInt();
System.out.println(num);
}
}
System 类底层就是调用了InputStream 类型的in 属性
public final static InputStream in = null;
所以可以这样操作:
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class mySystemIO {
public static void main(String[] args) throws IOException {
/*Scanner scanner = new Scanner(System.in);
System.out.print("请输入数字:");
int num = scanner.nextInt();
System.out.println(num);*/
InputStream is = System.in;
int n = is.read();
System.out.println(n);
// 所以实际上System类实现了键盘与程序之间的输入流IO
// 而Scanner scanner = new Scanner(System.in); 说名了System类监听到了(读到了)键盘的输入,将输入传到了Scanner类中进行处理。
}
}
另外此处的scanner类不仅可以扫描键盘输入还可以扫描文件内容。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class mySystemIO {
public static void main(String[] args) throws IOException {
/*Scanner scanner = new Scanner(System.in);
System.out.print("请输入数字:");
int num = scanner.nextInt();
System.out.println(num);*/
/*InputStream is = System.in;
int n = is.read();
System.out.println(n);*/
// 所以实际上System类实现了键盘与程序之间的输入流IO
// 而Scanner scanner = new Scanner(System.in); 说名了System类监听到了(读到了)键盘的输入,将输入传到了Scanner类中进行处理。
Scanner scanner = new Scanner(new FileInputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\1.txt")));
while(scanner.hasNext()){
System.out.println(scanner.next());
}
}
}
在System中不仅实现了InputStream 还实现了 PrintStream
import java.io.*;
import java.util.Scanner;
public class mySystemIO {
public static void main(String[] args) throws IOException {
PrintStream ps = System.out;
ps.println("123");
// 简写就是 System.out.println("123");
}
}
字节流如何转换称字符流?
将键盘输入内容存到文件中去
[xxx]StreamReader 可以将字节流转成字符流,以便提高效率。注意只能单向转换【字节流】—>【字符流】
import java.io.*;
public class mySystemIO {
public static void main(String[] args) throws IOException {
// 获取键盘输入流
InputStream in = System.in;
// 字节流转字符流
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
String str = bufferedReader.readLine();
while (!str.equals("---")){
bufferedWriter.write(str);
bufferedWriter.newLine();
str = bufferedReader.readLine();
}
bufferedWriter.close();
bufferedReader.close();
inputStreamReader.close();
in.close();
}
}
DataOutput[Input]Stream 数据流
操作基本数据类型
数据流
import java.io.*;
public class myDataOutputStream {
public static void main(String[] args) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
dataOutputStream.writeBoolean(true);
dataOutputStream.writeInt(12);
dataOutputStream.writeUTF("你好");
dataOutputStream.close();
}
}
输出内容:乱码
所以此处的输出内容不是直接输出的,而是经过程序的。
import java.io.*;
public class myDataOutputStream {
public static void main(String[] args) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
dataOutputStream.writeBoolean(true);
dataOutputStream.writeInt(12);
dataOutputStream.writeUTF("你好");
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
System.out.println(dataInputStream.readBoolean() + "," +
dataInputStream.readInt() + "," +
dataInputStream.readUTF()); // true,12,你好
dataOutputStream.close();
dataInputStream.close();
}
}
注意:
(1)先写出来,再读出来。否则直接输出看到的是乱码。
(2)读写是顺序不能乱,怎么写的就怎么读。
(3)可以实现IO 传输,客户端与客户端之间的通信。
ObjectOutput[Input]Stream 对象流
操作引用数据类型
对象流
import java.io.*;
class ObjectOutputStreamTestObject {
private String name;
private int age;
private double height;
public ObjectOutputStreamTestObject(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
public class myObjectOutputStream {
public static void main(String[] args) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
objectOutputStream.writeObject(new ObjectOutputStreamTestObject("小明",12,170.7));
objectOutputStream.close();
}
}
结果:报错(类没有序列化异常)
解决方法:序列化的类必须实现Serializable
class ObjectOutputStreamTestObject implements Serializable {
private String name;
private int age;
private double height;
public ObjectOutputStreamTestObject(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
查看输出文件:乱码
所以此处的输出内容不是直接输出的,是要经过程序将其读取进来的。
反序列化
import java.io.*;
class ObjectOutputStreamTestObject implements Serializable {
private String name;
private int age;
private double height;
public ObjectOutputStreamTestObject(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
public class myObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
ObjectOutputStreamTestObject obj = (ObjectOutputStreamTestObject)objectInputStream.readObject();
System.out.println(obj); //=> com.study.myFile.ObjectOutputStreamTestObject@5b6f7412
objectInputStream.close();
}
}
输出结果是:com.study.myFile.ObjectOutputStreamTestObject@5b6f7412
对ObjectOutputStreamTestObject 类重写toString()再执行,发现执行结果报错
Exception in thread "main" java.io.InvalidClassException: com.study.myFile.ObjectOutputStreamTestObject; local class incompatible: stream classdesc serialVersionUID = 6762953453798583304, local class serialVersionUID = 4471594530836362455
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1829)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2120)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:440)
at com.study.myFile.myObjectOutputStream.main(myObjectOutputStream.java:56)
原因:在写的时候传入的类对象中没有加入toString() 方法,但是在读的时候却执行了toString() 方法,没有定义uid所以程序就认为不是同一个类,因此处理方法:
类中加入序列版本号(点击类alt + enter【Add ‘serialVersionUID’】)
序列化版本号
import java.io.*;
class ObjectOutputStreamTestObject implements Serializable {
private static final long serialVersionUID = -6237412967763134270L;
private String name;
private int age;
private double height;
public ObjectOutputStreamTestObject(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "ObjectOutputStreamTestObject{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
public class myObjectOutputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
// objectOutputStream.writeObject(new ObjectOutputStreamTestObject("小明",12,170.7));
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
ObjectOutputStreamTestObject obj = (ObjectOutputStreamTestObject)objectInputStream.readObject();
System.out.println(obj); //=> ObjectOutputStreamTestObject{name='小明', age=12, height=170.7}
objectInputStream.close();
// objectOutputStream.close();
}
}
执行成功,输出:ObjectOutputStreamTestObject{name=‘小明’, age=12, height=170.7}
特定修饰符无效反序列化
(1) 如果变量加上transient 修饰读取的结果为null,或者说就不可以反序列化。
(2) 如果变量加上static 修饰读取的结果为null,或者说就不可以反序列化。
应用
10 条数据(对象)----> ArrayList ---->ObjectOutputStream ----> ObjectInputStream ----> for
import java.io.*;
import java.util.ArrayList;
import java.util.List;
class ArrayListAndObjectOutputStreamTest implements Serializable {
private static final long serialVersionUID = -6237412967763134270L;
private String name;
private int age;
public ArrayListAndObjectOutputStreamTest(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class ArrayListAndObjectOutputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
List<ArrayListAndObjectOutputStreamTest> arrList = new ArrayList<>();
arrList.add(new ArrayListAndObjectOutputStreamTest("xiaoming", 12));
arrList.add(new ArrayListAndObjectOutputStreamTest("xiaohau", 13));
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
objectOutputStream.writeObject(arrList);
ObjectInputStream objectInputStream = new ObjectInputStream(
new FileInputStream(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a\\b\\c\\2.txt")));
List list = (List)(objectInputStream.readObject());
for (Object o : list) {
System.out.println(o);
}
objectInputStream.close();
objectOutputStream.close();
}
}
复制整一个文件夹
import java.io.*;
public class myCopyDir {
public static void main(String[] args) throws IOException {
copyDir(new File("C:\\Users\\Jming_er\\Desktop\\工具\\a"), new File("C:\\Users\\Jming_er\\Desktop\\工具\\a2"));
}
private static void copyDir(File src, File target) throws IOException {
// 判断是否存在目标文件夹
if (!target.exists()) {
target.mkdirs();
}
File[] files = src.listFiles();
for (File file : files) {
if (file.isFile())
copyFile(file, new File(target + "\\" + file.getName())); // 拼接字符串
else
copyDir(file, new File(target + "\\" + file.getName())); // 拼接字符串
}
}
private static void copyFile(File src, File target) throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(target));
byte[] bt = new byte[1024 * 8];
int len = bufferedInputStream.read(bt);
while (len != -1) {
bufferedOutputStream.write(bt, 0, len);
len = bufferedInputStream.read(bt);
}
bufferedOutputStream.close();
bufferedInputStream.close();
}
}