百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

java 文件操作(I/O流)(java文件流写入文件)

wptr33 2025-06-10 18:39 6 浏览

一、文件操作技术演进




二、核心类对比分析

1. 传统IO vs NIO

特性

java.io

java.nio

数据流方向

单向流

通道双向传输

缓冲机制

需手动包装缓冲流

内置Buffer机制

非阻塞支持

不支持

Selector非阻塞模型

元数据操作

有限

完整属性支持

符号链接处理

不支持

支持

文件系统操作

基础功能

高级文件树遍历

2. 主要工具类对比

类名

用途

典型方法

java.io.File

传统文件元数据操作

exists(), mkdir(), listFiles()

java.nio.file.Path

NIO2路径操作核心类

toAbsolutePath(), resolve()

java.nio.file.Files

文件操作工具类(推荐使用)

copy(), readAllLines(), walk()


三、基础文件操作全解

1. 文件读写操作

文本文件处理

// 传统IO写法(需处理编码)
try (BufferedReader reader = new BufferedReader(
       new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8))) {
    String line;
    while ((line = reader.readLine()) != null) {
        process(line);
    }
}

// NIO2改进写法(Java8+)
List<String> lines = Files.readAllLines(Paths.get("data.txt"), StandardCharsets.UTF_8);
Files.write(Paths.get("output.txt"), lines, StandardOpenOption.CREATE);

二进制文件处理

// 小文件快速读写
byte[] fileContent = Files.readAllBytes(Paths.get("image.jpg"));
Files.write(Paths.get("copy.jpg"), fileContent);

// 大文件分块处理(内存优化)
try (InputStream is = new FileInputStream("large.dat");
     OutputStream os = new FileOutputStream("copy.dat")) {
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1) {
        os.write(buffer, 0, bytesRead);
    }
}

2. 目录操作

// 创建多级目录
Path newDir = Paths.get("data/2023/08");
Files.createDirectories(newDir);

// 遍历目录树
try (Stream<Path> paths = Files.walk(Paths.get("."))) {
    paths.filter(Files::isRegularFile)
         .forEach(System.out::println);
}

// 文件搜索(Java8+)
PathMatcher matcher = FileSystems.getDefault()
    .getPathMatcher("glob:**/*.{java,class}");
Files.walk(Paths.get("src"))
     .filter(matcher::matches)
     .forEach(System.out::println);

四、NIO高级特性

1. 内存映射文件(大文件处理)

try (RandomAccessFile raf = new RandomAccessFile("huge.data", "rw");
     FileChannel channel = raf.getChannel()) {
    
    MappedByteBuffer buffer = channel.map(
        FileChannel.MapMode.READ_WRITE, 0, channel.size());
    
    // 直接操作内存缓冲区
    while (buffer.hasRemaining()) {
        byte b = buffer.get();
        // 处理字节数据
    }
}

2. 文件锁机制

try (FileChannel channel = FileChannel.open(Paths.get("data.lock"), 
       StandardOpenOption.WRITE)) {
    
    FileLock lock = channel.tryLock();
    if (lock != null) {
        try {
            // 执行排他操作
        } finally {
            lock.release();
        }
    }
}

3. 异步IO(Java7+)

AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(
    Paths.get("async.data"), StandardOpenOption.READ);

ByteBuffer buffer = ByteBuffer.allocate(1024);
asyncChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
    @Override
    public void completed(Integer result, ByteBuffer attachment) {
        // 处理读取完成
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        // 处理异常
    }
});

五、最佳实践指南

1. 文件操作规范

  • 路径处理:使用Paths.get()代替字符串拼接
  • 异常处理:捕获FileSystemException及其子类
  • 资源释放:优先使用try-with-resources
  • 符号链接:使用Files.isSymbolicLink()检测

2. 性能优化技巧

// 缓冲区大小选择(经验值)
int bufferSize = 64 * 1024; // 64KB
try (BufferedInputStream bis = new BufferedInputStream(
       new FileInputStream("large.iso"), bufferSize)) {
    // 读取操作
}

// 并行处理文件(Java8+)
Files.list(Paths.get("input"))
     .parallel()
     .forEach(this::processFile);

3. 安全注意事项

// 路径注入防护
String userInput = "malicious/../../etc/passwd";
Path safePath = Paths.get("baseDir").resolve(userInput).normalize();
if (!safePath.startsWith(Paths.get("baseDir"))) {
    throw new SecurityException("非法路径访问");
}

// 文件权限控制
Set<PosixFilePermission> perms = EnumSet.of(
    OWNER_READ, OWNER_WRITE, GROUP_READ);
Files.setPosixFilePermissions(Paths.get("secret.txt"), perms);

六、特殊场景处理

1. 临时文件管理

// 自动删除临时文件
Path tempFile = Files.createTempFile("data_", ".tmp");
try {
    // 使用临时文件
} finally {
    Files.deleteIfExists(tempFile); // 显式删除
}

// 使用ShutdownHook删除
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    try {
        Files.delete(tempFile);
    } catch (IOException e) {
        logger.error("临时文件删除失败", e);
    }
}));

2. 文件监控(WatchService)

try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
    Path dir = Paths.get("monitor");
    dir.register(watcher, 
        ENTRY_CREATE, 
        ENTRY_DELETE, 
        ENTRY_MODIFY);

    while (!Thread.currentThread().isInterrupted()) {
        WatchKey key = watcher.take();
        for (WatchEvent<?> event : key.pollEvents()) {
            Path changedFile = (Path) event.context();
            System.out.println("文件变更: " + changedFile);
        }
        key.reset();
    }
}

七、常见问题解决方案

Q1:如何正确比较文件内容?

// 高效比较大文件(Java12+)
long mismatch = Files.mismatch(Paths.get("file1"), Paths.get("file2"));
if (mismatch == -1L) {
    System.out.println("文件内容完全相同");
}

// 传统MD5校验方法
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(file)) {
    byte[] buffer = new byte[8192];
    int len;
    while ((len = is.read(buffer)) != -1) {
        md.update(buffer, 0, len);
    }
}
byte[] digest = md.digest();

Q2:如何处理中文文件名乱码?

// 指定文件系统编码
Path path = Paths.get("中文目录");
String fileName = new String(path.getFileName().toString().getBytes("GBK"), "ISO-8859-1");

// 统一使用UTF-8编码
System.setProperty("sun.jnu.encoding", "UTF-8");
System.setProperty("file.encoding", "UTF-8");

Q3:如何高效复制大文件?

// NIO零拷贝技术(推荐)
try (FileChannel source = FileChannel.open(src, StandardOpenOption.READ);
     FileChannel dest = FileChannel.open(dst, StandardOpenOption.WRITE)) {
    dest.transferFrom(source, 0, source.size());
}

// Java9优化版
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);

八、扩展工具推荐

1. Apache Commons IO

// 文件工具类
FileUtils.copyFile(srcFile, destFile);
List<String> lines = FileUtils.readLines(file, "UTF-8");

// 目录监控
FileAlterationMonitor monitor = new FileAlterationMonitor(5000);
FileAlterationObserver observer = new FileAlterationObserver("watchDir");
observer.addListener(new FileAlterationListenerAdaptor() {
    @Override
    public void onFileCreate(File file) {
        // 处理新建文件
    }
});

2. Java ZIP压缩

try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("out.zip"))) {
    Files.walk(Paths.get("compressDir"))
         .filter(Files::isRegularFile)
         .forEach(path -> {
             ZipEntry entry = new ZipEntry(path.toString());
             zos.putNextEntry(entry);
             Files.copy(path, zos);
             zos.closeEntry();
         });
}

掌握Java文件操作的关键要点:

  1. 优先使用NIO2(FilesPaths)API
  2. 正确处理字符编码和换行符差异
  3. 针对文件规模选择合适处理方式
  4. 严格管理资源释放和异常处理
  5. 重要操作添加事务回滚机制

建议在项目中:

  • 统一文件操作工具类
  • 建立文件路径白名单机制
  • 对大文件操作实施监控和日志记录
  • 定期进行文件系统安全审计

相关推荐

Java常用工具类技术文档(java常用util工具类)

一、概述Java工具类(UtilityClasses)是封装了通用功能的静态方法集合,能够简化代码、提高开发效率。本文整理Java原生及常用第三方库(如ApacheCommons、GoogleG...

建议收藏!深入理解Java虚拟机:JVM垃圾回收算法+垃圾收集器

02JVM垃圾回收算法2.1什么是垃圾回收?...

Java 开发者线上问题排查常用的 15 个 Linux 命令

作为Java开发者,线上环境的问题排查是日常工作的重要组成部分。熟练掌握Linux命令能大幅提升排查效率,快速定位进程异常、日志错误、性能瓶颈等核心问题。本文结合Java应用特点,整理1...

Java-Maven详解(maven for java)

一、什么是Maven?ApacheMaven是一个软件...

java 文件操作(I/O流)(java文件流写入文件)

一、文件操作技术演进二、核心类对比分析...

如何使用Java API操作HDFS系统?(java编程操作hdfs能完成的功能有)

1.搭建项目环境打开Eclipse选择FileàNewàMavenProject创建Maven工程,选择“Createasimpleproject”选项,点击【Next】按钮,会进入“New...

那些被&quot;删除&quot;却仍占用空间的文件

在服务器运维过程中,磁盘空间不足是一个常见问题。而有时候,即使清理了大量文件,系统仍然报告磁盘几乎已满,这种情况尤为令人困惑。本文将通过一个实际案例,分享如何排查和解决Linux服务器上的"幽...

SpringBoot的Web应用开发——Web缓存利器Redis的应用!

 Web缓存利器Redis的应用Redis是目前使用非常广泛的开源的内存数据库,是一个高性能的keyvalue数据库,它支持多种数据结构,常用做缓存、消息代理和配置中心。本节将简单介绍Redis的使...

如何使用C#中的Lambda表达式操作Redis Hash结构,简化缓存中对象属性的读写操作

...

Redis 常用命令大全(redis常用命令及详解)

Redis常用命令全解析在当今的数据处理与存储领域,Redis凭借其高性能、丰富的数据结构等特性,成为了众多开发者和企业的首选内存数据库。下面将为大家详细介绍Redis的常用命令。键(Key)...

Redis+Lua脚本防超卖是万能解?这3个致命漏洞你可能没发现!

在高并发秒杀场景中,Redis+Lua脚本常被视为防止超卖的“银弹”。然而,许多开发者因对其底层逻辑理解不足,踩中了致命漏洞却不自知。本文通过真实案例剖析三个隐藏极深的问题,并提供完整解决方案,助你避...

10w qps缓存数据库——Redis(缓存技术 redis)

一、Redis数据库介绍:Redis:非关系型缓存数据库...

Redis安装及核心数据结构(redis一般安装在哪)

Redis安装官方下载地址:http://redis.io/downloadhttp://download.redis.io/releases/...

Python Redis数据库新玩法:从零到高手掌握操作技巧

介绍Redis(RemoteDictionaryServer)是一种高性能的开源内存数据库,它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等,并提供了丰富的操作命令。Redis具有快速、...

redis知识总结(基础篇,可复习,可学习)

最近redis差不多看完了,前面学的也忘了好多,所以正好写篇博客复习复习。此篇介绍的是redis的基础篇,希望这篇能帮到各位大佬。...