在Java中,如果要将非ASCII文件名以zip方式添加,你需要确保在文件名中正确处理字符集和大小写。以下是一个使用Java Standard Edition (SE) 和Java Platform, Enterprise Edition (JEE) 中的java.util.zip操作的示例:
java.util.zip
和 java.io.File
。import java.util.zip.*;
import java.io.File;
File
对象和InputStream
接口来读取文件流。// File 对象表示要压缩的文件
File fileToZip = new File("/path/to/file.txt");
// 假设 inputStream 是要压缩的文件的 FileInputStream
InputStream inputStream = new FileInputStream(fileToZip);
java.util.zip.ZipOutputStream
创建一个ZIPOutputStream,将文件流添加到输出中,并用指定的文件名创建ZIPEntry对象。// ZIPOutputStream 用于存储压缩输出
ZipOutputStream zipOutputStream = new ZipOutputStream(System.out);
// 遍历目录中的所有文件,并将其添加到 ZIP 输出
File[] filesToZip = fileToZip.listFiles();
for (File file : filesToZip) {
try {
// 将文件名转换为小写以处理非 ASCII 文件名
String filenameLowerCase = file.getName().toLowerCase();
// 创建ZIPEntry对象并将文件流添加到输出
ZipEntry zipEntry = new ZipEntry(filenameLowerCase);
zipOutputStream.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int len;
FileInputStream fileInputStream = new FileInputStream(file);
while ((len = fileInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, len);
}
fileInputStream.close();
zipOutputStream.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// 关闭ZIPOutputStream以关闭zip流
zipOutputStream.close();
在Java SE中,你可以使用Path
和FileNameGenerator
来获取与字符集相关的文件名。首先,使用java.nio.file.Path转换文件名,将其转换为java.nio.Files
,然后使用java.nio.charset.StandardCharsets
将字符转换为与字节序无关的字符集。
在JEE中,使用StringEncoder
和CharsetEncoder
将字符转换为字节,并将字节映射到CharacterEncoder
以生成非ASCII文件名。然后使用ZipEntry
将生成的文件名添加到 ZIP 输出。
以下是在Java JEE中处理非ASCII文件名的示例:
// 引入需要的依赖包
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
import java.nio.file.*;
import java.nio.charset.spi.*;
import java.util.*;
import java.util.zip.*;
// UTF-8 编码器
Charset UTF8 = Charset.forName("UTF-8");
// 将字符集编码的字符串转换回字节数组
byte[] utf8ByteArray(String str) {
return str.getBytes(UTF8);
}
// 将字节数组转换回字符集编码的字符串
String utf8String(byte[] bytes) {
return new String(bytes, UTF8);
}
public class UnicodeFilenameEncoder {
private final StringEncoder defaultEncoder = new StringEncoder(UTF8);
private final CharacterEncoder nonDefaultEncoder = new UnicodeFilenameEncoder.NonDefaultCharacterEncoder();
private final Map<String, CharacterEncoder> stringEncoders = new HashMap<>();
UnicodeFilenameEncoder() {
stringEncoders.put("UTF-8", UTF8);
}
public static Path normalizeAndEncodeToFileSystemSafeName(Path file, CharsetEncoder encoder) {
return normalizeAndEncodeToFileSystemSafeName(file, encoder, (String)null);
}
public static Path normalizeAndEncodeToFileSystemSafeName(Path file, CharsetEncoder encoder, String fileExt) {
return normalizeAndEncodeToFileSystemSafeName(file.toFile(), encoder, fileExt);
}
public static Path normalizeAndEncodeToFileSystemSafeName(File file, CharsetEncoder encoder) {
return normalizeAndEncodeToFileSystemSafeName(file, encoder, (String)null);
}
public static Path normalizeAndEncodeToFileSystemSafeName(File file, CharsetEncoder encoder, String fileSuffix) {
String fileName = file.getName();
String name = file.getParent().getName();
String nameWithoutExtension = file.getName().substring(0, file.getName().lastIndexOf('.'));
fileName = utf8String(nonDefaultEncoder.encodeToString(utf8ByteArray((name.isEmpty() ? nameWithoutExtension : name).concat(fileName).concat(fileSuffix))))// 创建非默认的文件名
.replace('/','-');
return Paths.get(file.getPath()).toAbsolutePath()
.normalize()
.getRoot()
.getFileName()
.resolve(fileName);
}
public static class NonDefaultCharacterEncoder extends CharacterEncoderAdapter {
private Map<String, byte[]> encodingCache = new ConcurrentHashMap<>();
private CharsetEncoder fallbackEncoder = UTF8;
private Charset fallbackCharset;
private boolean cacheCharsetForThisPath;
public NonDefaultCharacterEncoder() {
fallbackCharset = new UTF8();
}
@Override
public int encodeToChar(byte[] bytes, int off, int len, char[] chars, int charOff) {
return fallbackEncoder.encode(bytes, off, len, createChars(chars, charOff, len), 0, chars.length);
}
private byte[][] createChars(char[] chars, int off, int len) {
if (cacheCharsetForThisPath) {
getChars(chars, off, len);
}
byte[][] bytes = encodingCache.get(fileName);
if (bytes == null) {
bytes = new byte[chars.length][];
getChars(chars, off, len, bytes);
encodingCache.put(fileName, bytes);
if (cacheCharsetForThisPath) {
getChars(chars, off, len);
}
}
return bytes;
}
private void getChars(char[] chars, int off, int len, byte[][] bytes) {
// 省略实现细节,将字符转换成字节,并根据指定的UTF-8编码进行转换
}
领取专属 10元无门槛券
手把手带您无忧上云