提升编程效率的API利器:精通Google Guava库之IO工具类

文摘   2024-10-06 20:02   湖北  

Java标准库中的I/O API虽然功能强大,但使用起来可能略显繁琐。为了简化这些操作,Google提供了Guava库,其中包含了一系列实用的I/O工具。

ByteStreams与CharStreams

Guava的ByteStreamsCharStreams类为处理字节流和字符流提供了便捷的方法。这两个类都包含了一系列静态实用方法,用于读取、写入、复制和操作流。

  • ByteStreams:专注于处理字节流,如InputStreamOutputStream。它提供了如toByteArray(InputStream)write(byte[] data, OutputStream)等方法,使得从输入流读取数据到字节数组或将字节数组写入输出流变得简单快捷。

  • CharStreams:与ByteStreams类似,但专注于处理字符流,如ReaderWriter。它提供了如toString(Reader)write(CharSequence data, Writer)等方法,方便地将字符流转换为字符串或将字符串写入字符流。

场景:从一个文件中读取数据,将这些数据转换为一个特定的字符集编码,处理这些数据,并最终写入到另一个文件中。

import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import com.google.common.io.Files;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class GuavaIOExample {

    public static void main(String[] args) {
        File inputFile = new File("input.txt");
        File outputFile = new File("output.txt");

        try {
            // 使用ByteStreams和Files工具类从文件中读取字节数据
            byte[] fileContentBytes = Files.toByteArray(inputFile);

            // 将字节数据转换为字符流,这里我们指定UTF-8编码
            // 使用CharStreams来读取和处理字符数据
            String fileContent = new String(fileContentBytes, Charsets.UTF_8);

            // 对文本内容进行处理将所有字符转换为大写
            String processedContent = fileContent.toUpperCase();

            // 将处理后的字符数据写回文件
            // 首先,我们将字符串转换回字节数据
            byte[] processedBytes = processedContent.getBytes(Charsets.UTF_8);

            // 使用Files和ByteStreams工具类将字节数据写入文件
            try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile))) {
                ByteStreams.write(processedBytes, outputStream);
            }

            System.out.println("File processed successfully.");

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

    // 注意:优化一版本
    public static void mainWithGuavaStreams(String[] args) throws IOException {
        File inputFile = new File("input.txt");
        File outputFile = new File("output.txt");

        // 使用Files工具类创建一个InputStream
        try (FileInputStream fileInputStream = new FileInputStream(inputFile);
             // 使用InputStreamReader将字节流转换为字符流,并指定UTF-8编码
             InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, Charsets.UTF_8);
             // 使用CharStreams.transform处理字符流(这里我们转换为大写)
             InputStreamReader transformedReader = new InputStreamReader(
                     new TransformingInputStream(inputStreamReader, character -> (char) Character.toUpperCase(character)),
                     Charsets.UTF_8);
             // 使用Files工具类创建一个OutputStream
             FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
             // 使用OutputStreamWriter将字符流转换回字节流
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, Charsets.UTF_8)) {

            // 使用CharStreams.copy将处理后的字符流复制到输出流
            CharStreams.copy(transformedReader, outputStreamWriter);

            System.out.println("File processed successfully with Guava streams.");
        }
    }

    // CharStreams没提供直接转换字符的功能,自定义一个TransformingInputStream
    private static class TransformingInputStream extends java.io.InputStream {
        private final InputStreamReader reader;
        private final java.util.function.IntFunction<Integer> transformer;

        public TransformingInputStream(InputStreamReader reader, java.util.function.IntFunction<Integer> transformer) {
            this.reader = reader;
            this.transformer = transformer;
        }

        @Override
        public int read() throws IOException {
            int character = reader.read();
            if (character == -1) {
                return -1;
            }
            return transformer.apply(character);
        }

        // 需要重写close方法以确保底层reader也被关闭
        @Override
        public void close() throws IOException {
            reader.close();
        }
    }
}

更简洁点: 使用Files.asCharSourceFiles.asCharSink,并结合stream流操作来处理文本文件:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

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

public class GuavaIOExamplePractical {

    public static void main(String[] args) {
        File inputFile = new File("input.txt");
        File outputFile = new File("output.txt");

        try {
            // 使用Files.asCharSource读取文件内容
            String content = Files.asCharSource(inputFile, Charsets.UTF_8).read();

            // 使用Java 8的流操作进行转换(这里转换为大写)
            String upperCaseContent = content.chars()
                    .mapToObj(c -> (char) c)
                    .map(String::valueOf)
                    .map(String::toUpperCase)
                    .reduce((a, b) -> a + b)
                    .orElse("");

            // 使用Files.asCharSink写入文件内容
            Files.asCharSink(outputFile, Charsets.UTF_8).write(upperCaseContent);

            System.out.println("File processed successfully with Guava and Java 8 streams.");

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

二、Files工具类

import com.google.common.io.Files;
import com.google.common.base.Charsets;

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

public class GuavaFilesExample {

    public static void main(String[] args) {
        // 使用Files.createTempFile方法创建一个临时文件
        File tempFile = null;
        try {
            tempFile = Files.createTempFile("guava_example"".txt");
            System.out.println("临时文件已创建: " + tempFile.getAbsolutePath());

            // 使用Files.asCharSink方法向文件写入数据
            Files.asCharSink(tempFile, Charsets.UTF_8).write("这是一些示例文本.");
            System.out.println("数据已写入文件.");

            // 使用Files.asCharSource方法读取文件内容
            String content = Files.asCharSource(tempFile, Charsets.UTF_8).read();
            System.out.println("从文件中读取的内容: " + content);

            // 创建一个新文件用于复制操作
            File newFile = new File("new_guava_example.txt");

            // 使用Files.copy方法复制文件
            Files.copy(tempFile, newFile);
            System.out.println("文件已成功复制到: " + newFile.getAbsolutePath());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 使用Files.delete方法删除文件
            if (tempFile != null && !tempFile.delete()) {
                System.out.println("临时文件删除失败.");
            } else {
                System.out.println("临时文件已成功删除.");
            }
        }
    }
}


太强 ! SpringBoot中出入参增强的5种方法 : 加解密、脱敏、格式转换、时间时区处理

太强 ! SpringBoot中优化if-else语句的七种绝佳方法实战

SpringBoot使用EasyExcel并行导出多个excel文件并压缩zip下载
提升编程效率的利器: Google Guava库中双向映射BitMap
从MySQL行格式原理看:为什么开发规范中不推荐NULL?数据是如何在磁盘上存储的?
SpringBoot中使用Jackson实现自定义序列化和反序列化控制的5种方式总结
提升编程效率的利器: Google Guava库之RateLimiter优雅限流
深入JVM逃逸分析原理:且看其如何提高程序性能和内存利用率
必知必会!MySQL索引下推:原理与实战

深入解析JVM内存分配优化技术:TLAB

SpringBoot中基于JWT的双token(access_token+refresh_token)授权和续期方案
SpringBoot中基于JWT的单token授权和续期方案
SpringBoot中Token登录授权、续期和主动终止的方案(Redis+Token)
微服务中token鉴权设计的4种方式总结
提升编程效率的API利器:精通Google Guava库区间范围映射RangeMap
SpringBoot中Jackson控制序列化和反序列化的注解和扩展点总结【收藏版】

SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载

SpringBoot中基于XXL-JOB实现大量数据灵活控制的分片处理方案

提升编程效率的API利器:精通Google Guava库二维映射表Table

提升编程效率的利器: Google Guava库中双向映射BitMap
关注『 码到三十五 』,日有所获
                     点赞 和 在看 就是最大的支持

码到三十五
主要分享正经的开发技术(原理,架构,实践,源码等),以输出驱动输入;当然偶尔会穿插点生活琐碎,顺便吃个瓜,目的嘛,搞点精准流量,看能不能发发广告。
 最新文章