Zip ByteArray 解压缩 returns null 但输入流有效
Zip ByteArray decompression returns null but input stream is valid
所以我试图在内存中压缩一个 csv 文件,将其作为 BLOB 存储在 MYSQL 中,然后获取并解压缩它,但是 ZipInputStream.getEntry returns null 和我真的无法解压文件,我什么都试过了,我真的找不到答案。
我第一次 compressed/decompressed 文件使用 GZIP 并工作,但它改变了 CSV 文件结构,所以这就是我尝试使用 Zip 的原因。
CSV 文件通过 Spring 的 MultipartFile.getBytes().
从前端接收
这是从数据库中看到的压缩文件header
(header 似乎有效)
00000000 50 4B 03 04 14 00 08 08 08 00 B4 A0 8F 50 00 00 PK........´ .P..
提前致谢!
压缩方式:
@Throws(Exception::class)
fun compressFile(file : ByteArray) : ByteArray {
val baos = ByteArrayOutputStream()
val zos = ZipOutputStream(baos)
val entry = ZipEntry("data.csv")
entry.size = file.size.toLong()
zos.putNextEntry(entry)
zos.write(file)
zos.closeEntry()
zos.close()
return baos.toByteArray()
}
解压方法:
@Throws(Exception::class)
fun decompressFile(file : ByteArray): ByteArray {
if (file.isEmpty()) return file
val gis = ZipInputStream(ByteArrayInputStream(file))
val bf = BufferedReader(InputStreamReader(gis, "UTF-8"))
var outStr = ""
var line: String
while (bf.readLine().also { line = it ?: "" } != null) {
outStr += line
}
gis.close()
bf.close()
return outStr.toByteArray()
}
The ZipInputStream object after init
要阅读 ZipInputStream
,您必须在阅读前调用 getNextEntry()
。
对于这个例子,我创建了一个包含 2 个文件的 zip 文件:
foo.text
内容 Foo Bar
hello.txt
内容 Hello World
这里的代码表明在调用 getNextEntry()
之前尝试读取将不会产生任何结果:
public static void main(String[] args) throws Exception {
try (ZipInputStream zip = new ZipInputStream(new FileInputStream("C:\Temp\foo.zip"))) {
BufferedReader reader = new BufferedReader(new InputStreamReader(zip, "UTF-8"));
// read before getNextEntry() finds nothing
printText(reader);
ZipEntry zipEntry;
while ((zipEntry = zip.getNextEntry()) != null) {
System.out.println("Entry Name: " + zipEntry.getName() + " Size: " + zipEntry.getSize());
// read after getNextEntry() finds only the entry's content
printText(reader);
}
}
}
static void printText(BufferedReader reader) throws IOException {
int count = 0;
for (String line; (line = reader.readLine()) != null; count++)
System.out.println(" " + line);
System.out.println(count + " lines");
}
输出
0 lines
Entry Name: foo.txt Size: 7
Foo Bar
1 lines
Entry Name: hello.txt Size: 11
Hello World
1 lines
所以我试图在内存中压缩一个 csv 文件,将其作为 BLOB 存储在 MYSQL 中,然后获取并解压缩它,但是 ZipInputStream.getEntry returns null 和我真的无法解压文件,我什么都试过了,我真的找不到答案。 我第一次 compressed/decompressed 文件使用 GZIP 并工作,但它改变了 CSV 文件结构,所以这就是我尝试使用 Zip 的原因。 CSV 文件通过 Spring 的 MultipartFile.getBytes().
从前端接收这是从数据库中看到的压缩文件header (header 似乎有效)
00000000 50 4B 03 04 14 00 08 08 08 00 B4 A0 8F 50 00 00 PK........´ .P..
提前致谢!
压缩方式:
@Throws(Exception::class)
fun compressFile(file : ByteArray) : ByteArray {
val baos = ByteArrayOutputStream()
val zos = ZipOutputStream(baos)
val entry = ZipEntry("data.csv")
entry.size = file.size.toLong()
zos.putNextEntry(entry)
zos.write(file)
zos.closeEntry()
zos.close()
return baos.toByteArray()
}
解压方法:
@Throws(Exception::class)
fun decompressFile(file : ByteArray): ByteArray {
if (file.isEmpty()) return file
val gis = ZipInputStream(ByteArrayInputStream(file))
val bf = BufferedReader(InputStreamReader(gis, "UTF-8"))
var outStr = ""
var line: String
while (bf.readLine().also { line = it ?: "" } != null) {
outStr += line
}
gis.close()
bf.close()
return outStr.toByteArray()
}
The ZipInputStream object after init
要阅读 ZipInputStream
,您必须在阅读前调用 getNextEntry()
。
对于这个例子,我创建了一个包含 2 个文件的 zip 文件:
foo.text
内容Foo Bar
hello.txt
内容Hello World
这里的代码表明在调用 getNextEntry()
之前尝试读取将不会产生任何结果:
public static void main(String[] args) throws Exception {
try (ZipInputStream zip = new ZipInputStream(new FileInputStream("C:\Temp\foo.zip"))) {
BufferedReader reader = new BufferedReader(new InputStreamReader(zip, "UTF-8"));
// read before getNextEntry() finds nothing
printText(reader);
ZipEntry zipEntry;
while ((zipEntry = zip.getNextEntry()) != null) {
System.out.println("Entry Name: " + zipEntry.getName() + " Size: " + zipEntry.getSize());
// read after getNextEntry() finds only the entry's content
printText(reader);
}
}
}
static void printText(BufferedReader reader) throws IOException {
int count = 0;
for (String line; (line = reader.readLine()) != null; count++)
System.out.println(" " + line);
System.out.println(count + " lines");
}
输出
0 lines
Entry Name: foo.txt Size: 7
Foo Bar
1 lines
Entry Name: hello.txt Size: 11
Hello World
1 lines