Java 字符串的 7zip 压缩
Java 7zip compression of a String
我想在 Java 中将手动定义的字符串压缩为 7z。这样我就可以将它转换为 base64。我发现许多示例将文件压缩到 7z,然后保存到新文件中。
我只是尝试了下一个代码,它正确地获取了文件并进行了压缩:
private static void addToArchiveCompression(SevenZOutputFile out, File file, String dir) throws IOException {
String name = dir + File.separator + file.getName();
if (file.isFile()){
SevenZArchiveEntry entry = out.createArchiveEntry(file, name);
out.putArchiveEntry(entry);
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[1024];
int count = 0;
while ((count = in.read(b)) > 0) {
out.write(b, 0, count);
}
out.closeArchiveEntry();
} else if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null){
for (File child : children){
addToArchiveCompression(out, child, name);
}
}
} else {
System.out.println(file.getName() + " is not supported");
}
}
但是如何将手动定义的字符串压缩为 7z 并将其转换为 byte[]?那么我可以将 byte[] 转换为 base64 并打印它,而无需生成或读取新文件?
因为您已经在使用包装字节数组的 commons-compress for 7zip compression you can create SevenZOutputFile(SeekableByteChannel)
instance with SeekableInMemoryByteChannel
。根据 javadoc:
A SeekableByteChannel implementation that wraps a byte[].
When this channel is used for writing an internal buffer grows to accommodate incoming data. A natural size limit is the value of Integer.MAX_VALUE. Internal buffer can be accessed via array().
类似于:
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(new byte[1024]);
SevenZOutputFile out = new SevenZOutputFile(channel);
// modified addToArchiveCompression(out, ...); for String
// encode channel.array() to Base64
您当然必须对您发布的代码进行几处更改。该代码旨在压缩文件或目录,而您的情况要简单得多。例如,您绝对不需要 for
循环。
我分解了您必须研究的各个部分,并将编码留给您。
将字符串转换为 7z 数据:
其中一个选项是使用 ByteArrayInputStream
而不是 FileInputStream
。 ByteArrayInputStream
必须使用与字符串对应的字节进行初始化。
有关如何进行此转换的示例,请参阅以下文章:
https://www.baeldung.com/convert-string-to-input-stream
正在将输出字节转换为 Base64:
有几种方法,在此 Whosebug 线程中有详细说明:
How do I convert a byte array to Base64 in Java?
将 7z 输出到内存而不是文件:
您将不得不使用 SevenZOutputFile
构造函数,将 SeekableByteChannel
接口作为输入。 SeekableByteChannel
的实现必须由字节数组或各种流支持。您可以使用以下实现:
从文件以外的东西获取 SevenZArchiveEntry
:
虽然 SevenZOutputFile
class 似乎没有提供执行此操作的工具,但如果您查看其源代码,您会发现您可以手动创建一个 SevenZArchiveEntry
没有任何中介,因为它有一个空的构造函数。您必须 "pretend" 它仍然是一个实际文件,但这应该不是问题。
SevenZArchiveEntry
的源代码:
这有点离题,但假设 LZMA 是 7zip 的一部分,这可能对您有所帮助:
public static byte[]compress(byte[]arr,int level){
try {
ByteArrayOutputStream compr = new ByteArrayOutputStream();
LZMA2Options options = new LZMA2Options();
options.setPreset(level); // play with this number: 6 is default but 7 works better for mid sized archives ( > 8mb)
XZOutputStream out = new XZOutputStream(compr, options);
out.write(arr);
out.finish();
return compr.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static byte[]decompress(byte[]bts){
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bts);
XZInputStream is = new XZInputStream(bis);
ByteArrayInputStream decomp = new ByteArrayInputStream(is.readAllBytes());
ObjectInputStream ois = new ObjectInputStream(decomp);
byte data[]= (byte[]) ois.readObject();
return data;
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
maven 依赖:
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.8</version>
</dependency>
使用 s.getBytes(StandardCharsets.UTF_8);
将您的字符串转换为 byte[]
我想在 Java 中将手动定义的字符串压缩为 7z。这样我就可以将它转换为 base64。我发现许多示例将文件压缩到 7z,然后保存到新文件中。
我只是尝试了下一个代码,它正确地获取了文件并进行了压缩:
private static void addToArchiveCompression(SevenZOutputFile out, File file, String dir) throws IOException {
String name = dir + File.separator + file.getName();
if (file.isFile()){
SevenZArchiveEntry entry = out.createArchiveEntry(file, name);
out.putArchiveEntry(entry);
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[1024];
int count = 0;
while ((count = in.read(b)) > 0) {
out.write(b, 0, count);
}
out.closeArchiveEntry();
} else if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null){
for (File child : children){
addToArchiveCompression(out, child, name);
}
}
} else {
System.out.println(file.getName() + " is not supported");
}
}
但是如何将手动定义的字符串压缩为 7z 并将其转换为 byte[]?那么我可以将 byte[] 转换为 base64 并打印它,而无需生成或读取新文件?
因为您已经在使用包装字节数组的 commons-compress for 7zip compression you can create SevenZOutputFile(SeekableByteChannel)
instance with SeekableInMemoryByteChannel
。根据 javadoc:
A SeekableByteChannel implementation that wraps a byte[].
When this channel is used for writing an internal buffer grows to accommodate incoming data. A natural size limit is the value of Integer.MAX_VALUE. Internal buffer can be accessed via array().
类似于:
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(new byte[1024]);
SevenZOutputFile out = new SevenZOutputFile(channel);
// modified addToArchiveCompression(out, ...); for String
// encode channel.array() to Base64
您当然必须对您发布的代码进行几处更改。该代码旨在压缩文件或目录,而您的情况要简单得多。例如,您绝对不需要 for
循环。
我分解了您必须研究的各个部分,并将编码留给您。
将字符串转换为 7z 数据:
其中一个选项是使用 ByteArrayInputStream
而不是 FileInputStream
。 ByteArrayInputStream
必须使用与字符串对应的字节进行初始化。
有关如何进行此转换的示例,请参阅以下文章:
https://www.baeldung.com/convert-string-to-input-stream
正在将输出字节转换为 Base64:
有几种方法,在此 Whosebug 线程中有详细说明:
How do I convert a byte array to Base64 in Java?
将 7z 输出到内存而不是文件:
您将不得不使用 SevenZOutputFile
构造函数,将 SeekableByteChannel
接口作为输入。 SeekableByteChannel
的实现必须由字节数组或各种流支持。您可以使用以下实现:
从文件以外的东西获取 SevenZArchiveEntry
:
虽然 SevenZOutputFile
class 似乎没有提供执行此操作的工具,但如果您查看其源代码,您会发现您可以手动创建一个 SevenZArchiveEntry
没有任何中介,因为它有一个空的构造函数。您必须 "pretend" 它仍然是一个实际文件,但这应该不是问题。
SevenZArchiveEntry
的源代码:
这有点离题,但假设 LZMA 是 7zip 的一部分,这可能对您有所帮助:
public static byte[]compress(byte[]arr,int level){
try {
ByteArrayOutputStream compr = new ByteArrayOutputStream();
LZMA2Options options = new LZMA2Options();
options.setPreset(level); // play with this number: 6 is default but 7 works better for mid sized archives ( > 8mb)
XZOutputStream out = new XZOutputStream(compr, options);
out.write(arr);
out.finish();
return compr.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static byte[]decompress(byte[]bts){
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bts);
XZInputStream is = new XZInputStream(bis);
ByteArrayInputStream decomp = new ByteArrayInputStream(is.readAllBytes());
ObjectInputStream ois = new ObjectInputStream(decomp);
byte data[]= (byte[]) ois.readObject();
return data;
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
maven 依赖:
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.8</version>
</dependency>
使用 s.getBytes(StandardCharsets.UTF_8);
将您的字符串转换为 byte[]