encode/decode 文件 java 使用 Base64

encode/decode file in java with Base64

我在 Java 中写了一个 encode/decode 文件,如下所示

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class Test {
    
    public static void encodeFile(String inputfile, String outputfile) throws IOException {
        byte[] input_file = Files.readAllBytes(Paths.get(inputfile));
        byte[] encodedBytes = Base64.getEncoder().encode(input_file);
        String encodedString =  new String(encodedBytes);
        
        File ff =  new File(outputfile);
        FileOutputStream fileOut = new FileOutputStream(ff);
        OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
        outStream.write(encodedString);
        outStream.flush();
    }
    
    public static void decodeFile(String encodedfilecontent, String decodedfile) throws IOException {   
        byte[] decoded = Base64.getDecoder().decode(encodedfilecontent);
        String decodedString =  new String(decoded);
        
        File ff =  new File(decodedfile);
        FileOutputStream fileOut = new FileOutputStream(ff);
        OutputStreamWriter outStream = new OutputStreamWriter(fileOut);
        outStream.write(decodedString);
        outStream.flush();
    }

    public static void main(String[] args) throws IOException {
        
        String inputfile = "C:\Users\John\Desktop\Files.zip";
        
        String outputfile = "C:\Users\John\Desktop\encoded.txt";
        
        encodeFile(inputfile, outputfile);
        
        String encodedfilecontent = new String(Files.readAllBytes(Paths.get(outputfile)));
        
        String decodedfile = "C:\Users\John\Desktop\DecodedFiles.zip";
        
        decodeFile(encodedfilecontent, decodedfile);

    }

}

以上代码有2个方法:
1- 将文件编码为 Base64 并将其写入文本文件
2-解码文本文件并将其写回新文件
所有 input/output 个文件都在桌面
我已经对此进行了测试,并且此编码和解码方法仅在输入文件是简单文本文件时才有效。如果输入文件是图像或像本例这样的 zip 文件,则解码文件将被破坏。你能解释一下为什么它坏成这样吗?

有没有办法将任何类型的文件普遍编码为 Base64 并解码回来?如果是的话,你能调整上面的代码来做到这一点吗?

在您的 decodeFile 方法中,您不应将 byte[] 转换为字符串。这将使用默认的平台字符编码,某些字节在该编码中可能没有意义。相反,您应该直接在输出文件中写入字节数组。

您没有关闭文件。当您将文本 (String/Reader/Writer) 用于二进制数据时,也会出现上述问题:数据损坏、速度较慢、双倍内存、未指定编码时依赖于平台。

最佳方案是不取内存中的字节,另外制作一个 8/5 大的 64 进制字节数组。

使用 try-with-resources 自动关闭文件,即使出现异常(如非法 Base 64 字符)也是如此。

public static void encodeFile(String inputFile, String outputFile)
        throws IOException {
    Path inPath = Paths.get(inputFile);
    Path outPath = Paths.get(outputFile);
    try (OutputStream out = Base64.getEncoder().wrap(Files.newOutputStream(outPath))) {
        Files.copy(inPath, out);
    }
}

public static void decodeFile(String encodedfilecontent, String decodedfile)
        throws IOException {
    Path inPath = Paths.get(encodedfilecontent);
    Path outPath = Paths.get(decodedfile);
    try (InputStream in = Base64.getDecoder().wrap(Files.newInputStream(inPath))) {
        Files.copy(in, outPath);
    }
}