java的FileInputStream流如何使用

发布时间:2021-12-12 17:56:02 作者:iii
来源:亿速云 阅读:176
# Java的FileInputStream流如何使用

## 目录
1. [FileInputStream概述](#一fileinputstream概述)
   - 1.1 [什么是FileInputStream](#11-什么是fileinputstream)
   - 1.2 [FileInputStream在IO体系中的位置](#12-fileinputstream在io体系中的位置)
2. [FileInputStream核心方法详解](#二fileinputstream核心方法详解)
   - 2.1 [构造方法](#21-构造方法)
   - 2.2 [read()方法](#22-read方法)
   - 2.3 [available()方法](#23-available方法)
   - 2.4 [skip()方法](#24-skip方法)
   - 2.5 [close()方法](#25-close方法)
3. [基础使用示例](#三基础使用示例)
   - 3.1 [读取单个字节](#31-读取单个字节)
   - 3.2 [读取字节数组](#32-读取字节数组)
   - 3.3 [完整文件读取](#33-完整文件读取)
4. [高级应用场景](#四高级应用场景)
   - 4.1 [大文件分块读取](#41-大文件分块读取)
   - 4.2 [与其他流配合使用](#42-与其他流配合使用)
   - 4.3 [文件复制实现](#43-文件复制实现)
5. [异常处理机制](#五异常处理机制)
   - 5.1 [FileNotFoundException处理](#51-filenotfoundexception处理)
   - 5.2 [IOException处理](#52-ioexception处理)
   - 5.3 [使用try-with-resources](#53-使用try-with-resources)
6. [性能优化建议](#六性能优化建议)
   - 6.1 [缓冲区大小选择](#61-缓冲区大小选择)
   - 6.2 [NIO替代方案](#62-nio替代方案)
   - 6.3 [内存映射文件](#63-内存映射文件)
7. [常见问题解答](#七常见问题解答)
   - 7.1 [中文乱码问题](#71-中文乱码问题)
   - 7.2 [文件锁定问题](#72-文件锁定问题)
   - 7.3 [资源释放问题](#73-资源释放问题)
8. [总结与最佳实践](#八总结与最佳实践)

## 一、FileInputStream概述

### 1.1 什么是FileInputStream

FileInputStream是Java I/O库中用于从文件系统中读取原始字节流的核心类。作为InputStream抽象类的直接子类,它专门用于处理文件输入操作,提供了多种从文件读取数据的方法。

关键特性:
- 字节导向:以字节为单位进行读取
- 顺序访问:支持顺序读取文件内容
- 不可逆:读取后无法回退(除非配合BufferedInputStream)
- 线程不安全:需自行处理多线程同步

### 1.2 FileInputStream在IO体系中的位置

Java I/O类层次结构:

java.lang.Object └─ java.io.InputStream └─ java.io.FileInputStream


相关接口实现:
- Closeable:标识可关闭的资源
- AutoCloseable(Java 7+):支持try-with-resources

## 二、FileInputStream核心方法详解

### 2.1 构造方法

```java
// 通过文件路径创建
FileInputStream fis1 = new FileInputStream("test.txt");

// 通过File对象创建
File file = new File("test.txt");
FileInputStream fis2 = new FileInputStream(file);

// 通过FileDescriptor创建(高级用法)
FileDescriptor fd = fis2.getFD();
FileInputStream fis3 = new FileInputStream(fd);

构造注意事项: 1. 文件不存在时抛出FileNotFoundException 2. 路径可以是相对路径或绝对路径 3. 创建后即保持文件打开状态

2.2 read()方法

三种重载形式:

int read() // 读取单个字节(0-255),EOF返回-1
int read(byte[] b) // 读取到字节数组,返回实际读取数
int read(byte[] b, int off, int len) // 带偏移量的读取

2.3 available()方法

int available = fis.available();

2.4 skip()方法

long skipped = fis.skip(1024); // 跳过1KB数据

2.5 close()方法

fis.close();

三、基础使用示例

3.1 读取单个字节

try (FileInputStream fis = new FileInputStream("test.txt")) {
    int content;
    while ((content = fis.read()) != -1) {
        System.out.print((char) content);
    }
} catch (IOException e) {
    e.printStackTrace();
}

3.2 读取字节数组

byte[] buffer = new byte[1024];
try (FileInputStream fis = new FileInputStream("largefile.bin")) {
    int bytesRead;
    while ((bytesRead = fis.read(buffer)) != -1) {
        processBytes(buffer, bytesRead);
    }
} catch (IOException e) {
    handleError(e);
}

3.3 完整文件读取

public static byte[] readFullFile(String path) throws IOException {
    try (FileInputStream fis = new FileInputStream(path);
         ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = fis.read(buffer)) != -1) {
            bos.write(buffer, 0, bytesRead);
        }
        return bos.toByteArray();
    }
}

四、高级应用场景

4.1 大文件分块读取

public void processLargeFile(String filePath, int chunkSize) {
    try (FileInputStream fis = new FileInputStream(filePath)) {
        byte[] buffer = new byte[chunkSize];
        int chunkNumber = 0;
        while (fis.available() > 0) {
            int read = fis.read(buffer);
            processChunk(buffer, read, chunkNumber++);
        }
    } catch (IOException e) {
        // 错误处理
    }
}

4.2 与其他流配合使用

// 转换为BufferedInputStream提高性能
try (InputStream bis = new BufferedInputStream(
        new FileInputStream("data.dat"), 8192)) {
    // 读取操作
}

// 转换为DataInputStream读取基本类型
try (DataInputStream dis = new DataInputStream(
        new FileInputStream("numbers.bin"))) {
    double d = dis.readDouble();
    int i = dis.readInt();
}

4.3 文件复制实现

public static void copyFile(String src, String dest) throws IOException {
    try (FileInputStream fis = new FileInputStream(src);
         FileOutputStream fos = new FileOutputStream(dest)) {
        byte[] buffer = new byte[8192];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            fos.write(buffer, 0, length);
        }
    }
}

五、异常处理机制

5.1 FileNotFoundException处理

try {
    FileInputStream fis = new FileInputStream("missing.txt");
} catch (FileNotFoundException e) {
    System.err.println("文件未找到: " + e.getMessage());
    // 可选:创建新文件或提示用户
}

5.2 IOException处理

try (FileInputStream fis = new FileInputStream("data.bin")) {
    // 读取操作
} catch (IOException e) {
    logger.error("IO操作失败", e);
    throw new CustomRuntimeException("处理文件失败", e);
}

5.3 使用try-with-resources

// Java 7+ 自动关闭资源
try (FileInputStream fis = new FileInputStream("auto_close.txt")) {
    // 使用流
} // 自动调用close()

六、性能优化建议

6.1 缓冲区大小选择

缓冲区大小 适用场景
512B-1KB 小文件处理
4KB-8KB 通用场景
16KB-64KB 大文件处理
1MB+ 视频等超大文件

6.2 NIO替代方案

// 使用Files类(Java 7+)
byte[] data = Files.readAllBytes(Paths.get("file.txt"));

// 使用FileChannel
try (FileChannel channel = FileChannel.open(Paths.get("large.bin"))) {
    ByteBuffer buffer = ByteBuffer.allocate(8192);
    while (channel.read(buffer) > 0) {
        buffer.flip();
        processBuffer(buffer);
        buffer.clear();
    }
}

6.3 内存映射文件

try (FileChannel channel = new RandomAccessFile("huge.dat", "r").getChannel()) {
    MappedByteBuffer buffer = channel.map(
        FileChannel.MapMode.READ_ONLY, 0, channel.size());
    // 直接操作内存缓冲区
}

七、常见问题解答

7.1 中文乱码问题

解决方案:

try (InputStreamReader isr = new InputStreamReader(
        new FileInputStream("text.txt"), "UTF-8")) {
    // 使用字符流读取
}

7.2 文件锁定问题

File file = new File("locked.txt");
if (!file.canRead()) {
    throw new IOException("文件被锁定或无权限");
}

7.3 资源释放问题

错误示范:

FileInputStream fis = null;
try {
    fis = new FileInputStream("file.txt");
    // ...
} finally {
    if (fis != null) {
        try {
            fis.close(); // 可能抛出异常
        } catch (IOException e) {
            // 被忽略的异常
        }
    }
}

正确做法(Java 7+):

try (FileInputStream fis = new FileInputStream("file.txt")) {
    // ...
} // 自动安全关闭

八、总结与最佳实践

最佳实践清单

  1. 始终使用try-with-resources
  2. 合理设置缓冲区大小(通常8KB)
  3. 大文件使用NIO或内存映射
  4. 及时处理IO异常
  5. 考虑使用BufferedInputStream包装
  6. 二进制文件使用字节流,文本文件考虑字符流

性能对比表

方法 10MB文件 1GB文件
单字节读取 1200ms 超时
8KB缓冲 45ms 4200ms
NIO FileChannel 32ms 3800ms
内存映射 28ms 3500ms

测试环境:JDK 17/Windows 10/SSD

最终建议

”`

推荐阅读:
  1. Java中FileInputStream指的是什么
  2. 如何使用FileInputStream读取文件数据

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java fileinputstream

上一篇:css3中的rem怎么使用

下一篇:C++ STL容器中红黑树部分模拟实现的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》