0

我按照 SO 中的几个示例从 zip 中获取图像文件,并将每个文件字节放入哈希图中:

final byte[] zip_file = ((CommonsMultipartFile) zip_file).getBytes();
zip_stream = new ZipInputStream(new ByteArrayInputStream(zip_file));

try {
    while ((entry = zip_stream.getNextEntry()) != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            BufferedOutputStream dest = new BufferedOutputStream(baos, BUFFER_SIZE);
                try {
                    int count = 0;
                    byte[] data = new byte[BUFFER_SIZE];

                    while ((count = zip_stream.read(data, 0, BUFFER_SIZE)) > 0) {
                        dest.write(data, 0, count);
                    }

                    dest.flush();

                    filelist.put(entry.getName(), baos.toByteArray());
                    baos.reset();
                } finally {
                    dest.close();
                }
            } finally {
                baos.close();
            }
        }
    } finally {
        zip_stream.close();
    }

稍后从 读取时filelist,字节数组将持久化为一个 java bean,就像这样

Customer customer = new Customer();
byte[] image = fileist.get(imageFileName);
customer.setImage(image);

Customer是一个 JPA 实体,该字段image具有@Lob类型。所以这部分应该没有任何问题。

可悲的是,在整个交易之后,有一些数据写入了“图像”字段,但是来自 Oracle(使用 SQL 开发人员)的字节无法组合到图像文件中,这意味着来自 oracle 的文件已损坏。一定有什么问题导致字节损坏。我怎样才能让它工作?

更新

使用更改输入流-输出流传输IOUtils.copy但仍然无法正常工作......但我觉得这里有问题但不知道如何解决。在下面的代码中,循环似乎适用于 zipInputStream 的每个条目,条目从未访问过而不是文件名,它看起来正常吗?

 try {
        while ((entry = zip_stream.getNextEntry()) != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                IOUtils.copy(zip_stream, baos);
            } finally {
                baos.close();
            }
            filelist.put(entry.getName(), baos.toByteArray());
        }
    } finally {
        zip_stream.close();
    }
4

1 回答 1

1

删除 baos.set 并将 filelist.put 移到 baos.close 之后。

老实说,我认为应该反向嵌套 dest 和 baos,而 dest.close 就足够了,意味着关闭 baos。

也可以用 getInputStream 代替 getBytes。

当然有带有;的IOUtils copy某处应该有一个带有“保持打开”标志的副本。


没有跳过目录条目,也没有调用 closeEntry。

    try {
        ZipInputStream zipInputStream = new ZipInputStream(
            new FileInputStream("D:/dev/... .zip"));
        ZipEntry zipEntry;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            System.out.println("- " + zipEntry.getName()
                + " #" + zipEntry.getSize());
            if (zipEntry.isDirectory()) {
                zipInputStream.closeEntry();
                continue;
            }

            long size = zipEntry.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File too large: " + zipEntry.getName());
            }
            int reserved = size == -1L ? 8192 : (int)size; 
            ByteArrayOutputStream baos = new ByteArrayOutputStream(reserved);
            IOUtils.copy(zipInputStream, baos);
            zipInputStream.closeEntry();

            baos.close();
            File file = new File("D:/dev/data/temp/" + zipEntry.getName());
            file.getParentFile().mkdirs();
            FileUtils.writeByteArrayToFile(file, baos.toByteArray());
        }
    } catch (IOException ex) {
        Logger.getLogger(Stackoverflow.class.getName()).log(Level.SEVERE, null, ex);
    }
于 2013-05-28T14:45:46.263 回答