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流的分类

输入流:源文件—>程序

输出流:程序—>目标位置

字节流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q0UlSoq1-1653558872064)(imgclip.png "imgclip.png")]

字符流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKvtMcZq-1653558872069)(imgclip_1.png "imgclip_1.png")]

FileInputStream 类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dHtm25Pw-1653558892202)(imgclip.png "imgclip.png")]

  1. 获取文件内容
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();
    }
}

但是这样做如果文件内容比较大时效率就会低。

  1. 引入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();
    }
}

文件内容的复制

  1. 按照字节读取
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();
    }
}

  1. 使用缓冲数组
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个字节。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F0Hx14vR-1653558935823)(imgclip.png "imgclip.png")]

解决方法,规定输出数组长度

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();
    }
}

输出内容:乱码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DApGPsnd-1653559027718)(imgclip.png "imgclip.png")]

所以此处的输出内容不是直接输出的,而是经过程序的。

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();
    }
}

结果:报错(类没有序列化异常)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZctzw51-1653559122779)(imgclip.png "imgclip.png")]

解决方法:序列化的类必须实现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;
    }
}

查看输出文件:乱码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gmnHRhAr-1653559122781)(imgclip_1.png "imgclip_1.png")]

所以此处的输出内容不是直接输出的,是要经过程序将其读取进来的。

反序列化

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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值