Java IO(Input输入/Output输出)框架扮演着至关重要的角色,它是数据交换和文件处理的基石。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。
图片
一、Java IO体系概览Java IO 流有40多个类,他们都是从如下 4 个抽象类基类中派生出来的。抽象基类字节流字符流输入流InputStreamReader输出流OutputStreamWriter字节流和字符流有什么区别字节流:以字节(8位)为单位进行数据的读写。它是计算机中最基本的数据传输单元,适用于处理包括文本、图像、音频、视频等在内的二进制数据。字符流:以字符为单位进行数据的读写。字符流在处理时,会根据指定的字符编码(如UTF-8、GBK等)将字符转换为字节进行处理。由于一个字符可能占用多个字节(具体取决于编码方式),主要用于处理文本数据。IO 流的分类类型名称说明按功能分输入流,输出流输入流的类以InputStream, Reader为后缀。输出流的类以OutputStream, Writer未后缀。按照类型分字节流、字符流节点流的类以InputStream,OutputStream为后缀,字符流以Reader,Writer为后缀按角色或功能层次节点流(低级流、原始流)、包装流(处理流、高级流)节点流 它是直接从数据源或目的地读写数据的流。除了对原数据进行读取的节点流外,其他都是包装流下图展示IO流系统图-常用的类
图片
二、IO操作之文件与目录的操作介绍File类,包括如何创建、删除文件或目录,检查文件属性等。package file;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class studyOfFile {

@Test
public void createFile() throws IOException {
    String filePath = "/Users/wu/file";
    File file = new java.io.File(filePath);
    /*创建文件*/
    file.createNewFile();

    /*查看文件的一下属性*/
    System.out.println("创建文件成功 ~");
    System.out.println("文件名字: " + file.getName());
    System.out.println("文件是否存在: " + file.exists());
    System.out.println("文件是否是文件: " + file.isFile());
    System.out.println("文件的路径: " + file.getAbsolutePath());
    System.out.println("文件是否拥有读权限 " + file.canRead());
    System.out.println("文件是否存在: " + file.exists());

    /*删除文件*/
    file.delete();
    System.out.println("删除文件成功 ~");
    System.out.println("文件是否存在: " + file.exists());
}

@Test
public void createDirectory() {
    String directory = "/Users/wu/studyIo";
    File file = new java.io.File(directory);
    /*创建目录*/
    file.mkdir();

    /*查看目录的一下属性*/
    System.out.println("创建目录成功 ~");
    System.out.println("文件是否是文件: " + file.isFile());
    System.out.println("文件是否是目录: " + file.isDirectory());

    /*删除目录*/
    file.delete();
    System.out.println("删除目录成功 ~");
    System.out.println("目录是否存在: " + file.exists());
}

}
文件操作执行结果:
图片
目录操作的执行结果:
图片
三、以案例学习OI流在本小节将展示一下内容:字节流:FileInputStream和FileOutStream字符流:FileReader和FileWiter包装流:BufferedInputStream<-- FileReader和FileWiter的用法和下面的例子很类似,就不在写demo了-->FileInputStream例子这个例子将演示如何使用FileInputStream来读取文件内容,并使用FileOutputStream将读取的内容写入另一个文件。package demo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamExample {

public static void main(String[] args) {
    String sourcePath = "/Users/wu/studyIo/source.txt";
    String targetPath = "/Users/wu/studyIo/target.txt";

    FileInputStream fis = null;
    FileOutputStream fos = null;

    try {
        /*创建一个source.txt文件 用于从source.txt文件中读取去数据*/
        fis = new FileInputStream(sourcePath);
        /*创建一个target.txt文件 用于将读到的数据写到target.txt文件中*/
        fos = new FileOutputStream(targetPath);


        /*设置缓冲区的大小 一次读取1024字节*/
        byte[] buffer = new byte[1024];
        int length;

        /*read方法放回读取的字节数,读取完毕返回-1*/
        while ((length = fis.read(buffer)) > -1) {
            /*边读边写*/
            fos.write(buffer, 0, length);
        }

        System.out.println("文件复制完成。");

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fis != null) {
            try {
                /*记得关闭 释放资源*/
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fos != null) {
            try {
                /*真正执行写的操作,否则写入不成功*/
                fos.write(0);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

}

这里我遇到了一个问题:fis = new FileInputStream(sourcePath);按理可以直接创建文件的。因为它的源代码是这样写的
图片
我会报错
图片
手动创建上两个文件就不会报错了。至于为什么不创建文件而报错,我也没想明白。BufferedInputStream例子这个例子将展示如何使用BufferedInputStream来提高文件读取的效率。package demo;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedStreamExample {

public static void main(String[] args) {
    String sourcePath = "/Users/wu/studyIo/source.txt";
    BufferedInputStream bis = null;

    try {
        bis = new BufferedInputStream(new FileInputStream(sourcePath));

        int data = bis.read();

        while (data != -1) {
            System.out.print((char) data);
            data = bis.read();
        }

        System.out.println("\n文件读取完成。");

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

}运行结果:
图片
这里面会出现乱码问题,原因是用的是BufferedInputStream他是字节流,一个中文是占3个字节,它将他分成了一个一个字节读,就会乱码,把BufferedInputStream换为BufferedReader字符流就可以解决乱码问题。(要考虑文件编码格式)四、以对象处理流来学习序列化和反序列化序列化:保持数据时,保持数据的值和数据类型反序列化:恢复数据时,恢复数据的值和数据类型package demo;

import java.io.*;

public class SerializationDemo {

public static void main(String[] args) {
    String sourcePath = "/Users/wu/studyIo/employee.txt";

    // 序列化过程
    try (FileOutputStream fileOut = new FileOutputStream(sourcePath);
         ObjectOutputStream out = new ObjectOutputStream(fileOut)) {

        Employee emp = new Employee("John Doe", 30);
        out.writeObject(emp);
        System.out.println("Serialized data is saved in employee.ser");

    } catch (IOException i) {
        i.printStackTrace();
    }

    // 反序列化过程
    Employee emp = null;
    try (FileInputStream fileIn = new FileInputStream(sourcePath);
         ObjectInputStream in = new ObjectInputStream(fileIn)) {

        emp = (Employee) in.readObject();
        System.out.println("Deserialized Employee...");
        System.out.println("Employee : " + emp);

    } catch (IOException i) {
        i.printStackTrace();
        return;
    } catch (ClassNotFoundException c) {
        System.out.println("Employee class not found");
        c.printStackTrace();
        return;
    }
}

}


已注销
1 声望1 粉丝