java - 无法从 ZipInputStream 字节数组在 Oracle 中写入图像

标签 java spring jakarta-ee jpa

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

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();
    }

最佳答案

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

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

也可以使用 getInputStream 代替 getBytes。

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

<小时/>

未跳过目录条目且未调用 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);
    }

关于java - 无法从 ZipInputStream 字节数组在 Oracle 中写入图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16783466/

相关文章:

java - NullPointerException 未引用任何对象

java - 用正则表达式替换第一个

java - 如何从 spring application.yml 设置 "max_allowed_packet"属性

java - 如何为我的程序创建环境变量

java - Shared.loader 中的 Tomcat 环境变量触发警告

java - Spring配置服务器找不到纯文本文件

java - 无法从元组实例化类

jsf - "IllegalArgumentException: Can not set [EJB interface] field [managed bean field] to com.sun.proxy.$Proxy[some number]"与 OmniFaces 的@Eager

java - 集群环境下的hibernate一级缓存

java - 如何在浏览器关闭后保留 session ?