You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从MySQL Blob恢复存入的ArrayList<String>?读取时遇文件未找到异常

问题分析与解决方案

你遇到的FileNotFoundException核心原因是你存入数据库的并不是ArrayList的序列化数据,而是File对象本身——File对象序列化后仅保存了文件的路径信息,完全不包含文件里的内容。再加上你设置了tempFile.deleteOnExit(),当JVM退出后临时文件会被自动删除,后续读取时自然找不到这个路径对应的文件了。

错误点拆解

  • 写入环节:preparedStatement.setObject(1, tempFile)执行的是对File对象的序列化,存入Blob的只是文件路径字符串,不是myList的序列化数据。
  • 读取环节:你读出来的是之前序列化的File对象,但这个文件已经被删除(或者在不同运行环境中根本不存在),打开它时自然会抛出找不到文件的异常。

修正方案:直接序列化ArrayList到Blob(跳过无效的临时文件中转)

方案1:跳过临时文件,直接序列化ArrayList到字节数组存入Blob

这是最高效的方式,不需要临时文件做中转:

写入代码

ArrayList<String> myList = new ArrayList<>();
// 直接将ArrayList序列化到字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
    oos.writeUnshared(myList);
    oos.flush();
    byte[] listBytes = baos.toByteArray();

    // 存入数据库Blob列
    String insertQuery = "INSERT INTO table (tempFile) VALUES (?)";
    try (PreparedStatement pstmt = connection.prepareStatement(insertQuery)) {
        pstmt.setBytes(1, listBytes);
        pstmt.executeUpdate();
    }
} catch (IOException | SQLException e) {
    e.printStackTrace();
}

读取代码

String selectQuery = "SELECT tempFile FROM table WHERE ..."; // 补充你的查询条件
try (PreparedStatement pstmt = connection.prepareStatement(selectQuery);
     ResultSet rs = pstmt.executeQuery()) {
    if (rs.next()) {
        // 从Blob中读取字节数组,直接反序列化为ArrayList
        byte[] listBytes = rs.getBytes("tempFile");
        try (ByteArrayInputStream bais = new ByteArrayInputStream(listBytes);
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            ArrayList<String> myList = (ArrayList<String>) ois.readObject();
            System.out.println(myList.size());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
} catch (SQLException | IOException e) {
    e.printStackTrace();
}

方案2:若必须用临时文件,需读取文件内容存入Blob

如果你因为某些原因必须保留临时文件步骤,那要把文件里的序列化数据读出来存入Blob,而不是存File对象:

修正后的写入代码

ArrayList<String> myList = new ArrayList<>();
File tempFile = File.createTempFile("myFile", ".temp");
tempFile.deleteOnExit();

// 将ArrayList写入临时文件
try (FileOutputStream fos = new FileOutputStream(tempFile);
     ObjectOutputStream oos = new ObjectOutputStream(fos)) {
    oos.writeUnshared(myList);
}

// 读取临时文件的内容为字节数组
byte[] fileContent = Files.readAllBytes(tempFile.toPath());

// 存入数据库
String insertQuery = "INSERT INTO table (tempFile) VALUES (?)";
try (PreparedStatement pstmt = connection.prepareStatement(insertQuery)) {
    pstmt.setBytes(1, fileContent);
    pstmt.executeUpdate();
} catch (IOException | SQLException e) {
    e.printStackTrace();
}

读取代码和方案1一致,直接从Blob字节数组反序列化即可,无需再操作File对象。

关键注意事项

  • 确保ArrayList里的元素(这里是String)都是可序列化的(String本身已经实现Serializable接口,所以没问题)。
  • 序列化和反序列化的类结构要完全一致,否则会抛出ClassNotFoundException或InvalidClassException。

内容的提问来源于stack exchange,提问作者user3202153

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:36:16