Java-IO-小记
字数 2241 2025-08-11 21:26:21

Java I/O 流详解

一、概述

I/O(input/output)流是Java中用于输入输出的核心机制,定义在java.io包中。I/O流可以分为以下几类:

  1. 按数据单位分类

    • 字节流:以字节为单位
    • 字符流:以字符为单位
  2. 按传输方向分类

    • 输入流
    • 输出流
  3. 按功能分类

    • 节点流(低级流):直接连接数据源进行读写
    • 处理流(高级流):对已存在的节点流进行封装

Java I/O中有四个顶级类:

  • 字节流:InputStreamOutputStream
  • 字符流:ReaderWriter

二、字节流

1. FileInputStream和FileOutputStream

import java.io.*;

public class StreamTest {
    public static void main(String[] args) throws Exception {
        // 读取文件内容
        FileInputStream file_in = new FileInputStream("test.txt");
        int b = 0;
        while ((b = file_in.read()) != -1) {
            System.out.println(b); // 输出ASCII码
            System.out.println((char)b); // 转字符输出
        }
        file_in.close();
        
        // 写出文件
        FileOutputStream file_out = new FileOutputStream("test2.txt");
        String str1 = "hello world";
        file_out.write(str1.getBytes());
        file_out.close();
        
        // 文件复制
        FileInputStream copy_in = new FileInputStream("test.txt");
        FileOutputStream copy_out = new FileOutputStream("testCOPY2.txt");
        copy_out.write(copy_in.readAllBytes());
    }
}

read()方法有三种形式:

  • read():每次读一个字节
  • read(byte[] bs):读取多个字节到字节数组
  • read(byte[] bs, int offset, int len):跳过offset个字节读取len个字节

2. BufferedInputStream和BufferedOutputStream

字节缓冲流,内部自带8192字节的缓冲区。

import java.io.*;

public class StreamTest {
    public static void main(String[] args) throws Exception {
        BufferedInputStream buffer_in = new BufferedInputStream(
            new FileInputStream("test.txt"));
        BufferedOutputStream buffer_out = new BufferedOutputStream(
            new FileOutputStream("bufferOUT.txt"));
        buffer_out.write(buffer_in.readAllBytes());
        buffer_in.close();
        buffer_out.close();
    }
}

三、字符流

1. Reader

import java.io.*;

public class StreamTest {
    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("test.txt");
        int len1 = 0;
        while ((len1 = fr.read()) != -1) {
            System.out.println(((Object)len1).getClass().toString());
            System.out.println(len1);
        }
        fr.close();
    }
}

2. Writer

import java.io.*;

public class StreamTest {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("Writer.txt");
        fw.write("Java是世界上最好的语言.py");
        fw.close();
    }
}

四、转换流

InputStreamReaderOutputStreamWriter用于字节流和字符流之间的转换。

  • InputStreamReader:将字节输入流转换成字符输入流
  • OutputStreamWriter:将字节输出流转换成字符输出流

注意:只能对文本文件进行转换,图片、视频等非文本文件转换会导致数据丢失。

五、File类

File类用于封装文件或目录路径,提供文件操作功能。

1. 常用构造方法

File(File parent, String child);
File(String pathname);
File(String parent, String child);
File(URI uri);

2. 常用方法

方法 描述
getName() 返回文件或目录名称
getParent() 返回父路径名字符串
getParentFile() 返回父路径名的File对象
getPath() 转换为路径名字符串
isAbsolute() 测试是否为绝对路径
getAbsolutePath() 返回绝对路径
canRead() 测试是否可读
canWrite() 测试是否可写
exists() 测试是否存在
isDirectory() 测试是否为目录
isFile() 测试是否为标准文件
lastModified() 返回最后修改时间
length() 返回文件长度
createNewFile() 创建新文件
delete() 删除文件或目录
deleteOnExit() 虚拟机终止时删除
list() 返回目录中的文件和目录名数组
list(FilenameFilter filter) 返回满足过滤器的文件名数组
listFiles() 返回File对象数组
listFiles(FileFilter filter) 返回满足过滤器的File对象数组
mkdir() 创建目录
mkdirs() 创建目录及必需父目录
renameTo(File dest) 重命名文件

3. 文件过滤器

import java.io.*;
import java.util.Arrays;

public class FileTest {
    public static void main(String[] args) {
        File f = new File("C:\\JAVA");
        if (f.isDirectory()) {
            String[] filenames = f.list((dir, name) -> name.endsWith(".md"));
            Arrays.stream(filenames).forEach(ff -> System.out.println(ff));
        }
    }
}

六、RandomAccessFile

可以随机访问文件任意位置进行读写。

1. 构造方法

RandomAccessFile(File file, String mode);
RandomAccessFile(String name, String mode);

2. 常用方法

  • long getFilePointer():返回当前指针位置
  • void seek(long pos):设置文件指针偏移量
  • int skipBytes(int n):跳过n个字节

七、对象序列化

1. 序列化接口

  • Serializable:简单实现,系统自动完成
  • Externalizable:需手动实现方法,更灵活

2. serialVersionUID

private static final long serialVersionUID = 1L;

3. 示例

// SerializableTest.java
import java.io.*;

public class SerializableTest {
    public static void main(String[] args) throws Exception {
        // 序列化
        FileOutputStream fos1 = new FileOutputStream("test1.txt");
        ObjectOutputStream oos1 = new ObjectOutputStream(fos1);
        Person ps1 = new Person("test", 8848);
        oos1.writeObject(ps1);
        oos1.close();
        fos1.close();
        
        // 反序列化
        FileInputStream fis1 = new FileInputStream("test1.txt");
        ObjectInputStream ois1 = new ObjectInputStream(fis1);
        Person ps2 = (Person)ois1.readObject();
        fis1.close();
        ois1.close();
        ps2.getInfo();
    }
}

// Person.java
import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void getInfo() {
        System.out.println("name: " + name + " | age: " + age);
    }
}

八、NIO

JDK1.4引入的New I/O,核心组件:

  • Buffer
  • Channel
  • Selector

1. Buffer

Buffer子类:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

创建Buffer:

CharBuffer buffer = CharBuffer.allocate(10);

Buffer属性:

  • capacity:容量
  • limit:界限(可读区域的第一个索引)
  • position:下一个可读写的位置索引

示例:

import java.nio.CharBuffer;

public class FileTest {
    public static void main(String[] args) {
        CharBuffer cbf1 = CharBuffer.allocate(10);
        for (int i = 0; i <= 9; i++) {
            cbf1.put((char)i);
        }
        System.out.println(cbf1.capacity());
        System.out.println(cbf1.limit());
        System.out.println(cbf1.position());
        
        cbf1.flip(); // 反转缓冲区
        for (int i = 0; i <= 9; i++) {
            System.out.println((int)cbf1.get());
        }
    }
}

2. Channel

Channel实现类:

  • DatagramChannel:UDP通信
  • FileChannel:文件读写
  • Pipe.SinkChannel/Pipe.SourceChannel:线程间通信
  • ServerSocketChannel/SocketChannel:TCP通信

示例:

import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

public class FileTest {
    public static void main(String[] args) throws Exception {
        RandomAccessFile raf1 = new RandomAccessFile("test1.txt", "rw");
        RandomAccessFile raf2 = new RandomAccessFile("test2.txt", "rw");
        FileChannel fc1 = raf1.getChannel();
        FileChannel fc2 = raf2.getChannel();
        long transferto = fc1.transferTo(0, fc1.size(), fc2);
        System.out.println(transferto);
    }
}

3. NIO.2 (JDK7+)

新增内容:

  • java.nio.file
  • 全面的文件系统支持
  • 异步Channel I/O

3.1 Path接口

用于定位文件的对象。

3.2 Paths和Files工具类

Paths提供创建Path对象的静态方法:

Path path = Paths.get("example.txt");

Files提供操作文件的静态方法:

Files.copy(source, target);
Files.move(source, target);
Files.delete(path);
Files.readAllLines(path);
Java I/O 流详解 一、概述 I/O(input/output)流是Java中用于输入输出的核心机制,定义在 java.io 包中。I/O流可以分为以下几类: 按数据单位分类 : 字节流:以字节为单位 字符流:以字符为单位 按传输方向分类 : 输入流 输出流 按功能分类 : 节点流(低级流):直接连接数据源进行读写 处理流(高级流):对已存在的节点流进行封装 Java I/O中有四个顶级类: 字节流: InputStream 、 OutputStream 字符流: Reader 、 Writer 二、字节流 1. FileInputStream和FileOutputStream read() 方法有三种形式: read() :每次读一个字节 read(byte[] bs) :读取多个字节到字节数组 read(byte[] bs, int offset, int len) :跳过offset个字节读取len个字节 2. BufferedInputStream和BufferedOutputStream 字节缓冲流,内部自带8192字节的缓冲区。 三、字符流 1. Reader 2. Writer 四、转换流 InputStreamReader 和 OutputStreamWriter 用于字节流和字符流之间的转换。 InputStreamReader :将字节输入流转换成字符输入流 OutputStreamWriter :将字节输出流转换成字符输出流 注意 :只能对文本文件进行转换,图片、视频等非文本文件转换会导致数据丢失。 五、File类 File类用于封装文件或目录路径,提供文件操作功能。 1. 常用构造方法 2. 常用方法 | 方法 | 描述 | |------|------| | getName() | 返回文件或目录名称 | | getParent() | 返回父路径名字符串 | | getParentFile() | 返回父路径名的File对象 | | getPath() | 转换为路径名字符串 | | isAbsolute() | 测试是否为绝对路径 | | getAbsolutePath() | 返回绝对路径 | | canRead() | 测试是否可读 | | canWrite() | 测试是否可写 | | exists() | 测试是否存在 | | isDirectory() | 测试是否为目录 | | isFile() | 测试是否为标准文件 | | lastModified() | 返回最后修改时间 | | length() | 返回文件长度 | | createNewFile() | 创建新文件 | | delete() | 删除文件或目录 | | deleteOnExit() | 虚拟机终止时删除 | | list() | 返回目录中的文件和目录名数组 | | list(FilenameFilter filter) | 返回满足过滤器的文件名数组 | | listFiles() | 返回File对象数组 | | listFiles(FileFilter filter) | 返回满足过滤器的File对象数组 | | mkdir() | 创建目录 | | mkdirs() | 创建目录及必需父目录 | | renameTo(File dest) | 重命名文件 | 3. 文件过滤器 六、RandomAccessFile 可以随机访问文件任意位置进行读写。 1. 构造方法 2. 常用方法 long getFilePointer() :返回当前指针位置 void seek(long pos) :设置文件指针偏移量 int skipBytes(int n) :跳过n个字节 七、对象序列化 1. 序列化接口 Serializable :简单实现,系统自动完成 Externalizable :需手动实现方法,更灵活 2. serialVersionUID 3. 示例 八、NIO JDK1.4引入的New I/O,核心组件: Buffer Channel Selector 1. Buffer Buffer子类: ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer ShortBuffer 创建Buffer: Buffer属性: capacity:容量 limit:界限(可读区域的第一个索引) position:下一个可读写的位置索引 示例: 2. Channel Channel实现类: DatagramChannel:UDP通信 FileChannel:文件读写 Pipe.SinkChannel/Pipe.SourceChannel:线程间通信 ServerSocketChannel/SocketChannel:TCP通信 示例: 3. NIO.2 (JDK7+) 新增内容: java.nio.file 包 全面的文件系统支持 异步Channel I/O 3.1 Path接口 用于定位文件的对象。 3.2 Paths和Files工具类 Paths提供创建Path对象的静态方法: Files提供操作文件的静态方法: