java.io.IOException:流已关闭

2024-01-12

对于多图像检索,我正在调用PhotoHelperServlet使用锚标记来获取 imageNames(多个图像),如下所示

PhotoHelperServlet获取姓名Images

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// Getting userid from session

Image image = new Image();
image.setUserid(userid);

ImageDAO imageDAO = new ImageDAO();

try {

    List<Image> imageId = imageDAO.listNames(image);

    if (imageId == null) { 
        // check if imageId is retreived
    }

    request.setAttribute("imageId", imageId);

    //Redirect it to home page
    RequestDispatcher rd = request.getRequestDispatcher("/webplugin/jsp/profile/photos.jsp");
    rd.forward(request, response);

catch (Exception e) {
    e.printStackTrace();
}

在 ImageDAO listNames() 方法中:

public List<Image> listNames(Image image) throws IllegalArgumentException, SQLException, ClassNotFoundException {

    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultset = null;
    Database database = new Database();
    List<Image> imageId = new ArrayList<Image>();

    try {

        connection = database.openConnection();
        preparedStatement = connection.prepareStatement(SQL_GET_PHOTOID);                  
        preparedStatement.setLong(1, image.getUserid());
        resultset = preparedStatement.executeQuery();

        while(resultset.next()) {
            image.setPhotoid(resultset.getLong(1));
            imageId.add(image);
        }

    } catch (SQLException e) {
        throw new SQLException(e);
    } finally {
        close(connection, preparedStatement, resultset);
    }
    return imageId;
}

在JSP代码中:

<c:forEach items="${imageId}" var="imageid">
    <img src="Photos/${imageid}">
</c:forEach>

在 PhotoServlet doGet() 方法中获取照片:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String imageid = request.getPathInfo().substring(1);

if(imageid == null) {
    // check for null and response.senderror
}

ImageDAO imageDAO = new ImageDAO();

try {

    Image image = imageDAO.getPhotos(imageid);

    if(image == null) {}

    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    try {

        input = new BufferedInputStream(image.getPhoto(), DEFAULT_BUFFER_SIZE);
        output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

        // Write file contents to response.
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
    } finally {
        if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
        if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
    }

} catch(Exception e) {
    e.printStackTrace();
}

在 ImageDAO getPhotos() 方法中

public Image getPhotos(String imageid) throws IllegalArgumentException, SQLException, ClassNotFoundException {

    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultset = null;
    Database database = new Database();
    Image image = new Image();

    try {

        connection = database.openConnection();
        preparedStatement = connection.prepareStatement(SQL_GET_PHOTO);                  
        preparedStatement.setString(1, imageid);
        resultset = preparedStatement.executeQuery();

        while(resultset.next()) {
            image.setPhoto(resultset.getBinaryStream(1));
        }

    } catch (SQLException e) {
        throw new SQLException(e);
    } finally {
        close(connection, preparedStatement, resultset);
    }
    return image;
}

在 web.xml 中

<!-- Getting each photo -->
<servlet>
    <servlet-name>Photos Module</servlet-name>
    <servlet-class>app.controllers.PhotoServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Photos Module</servlet-name>
    <url-pattern>/Photos/*</url-pattern>
</servlet-mapping>

<!-- Getting photo names -->
<servlet>
    <servlet-name>Photo Module</servlet-name>
    <servlet-class>app.controllers.PhotoHelperServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Photo Module</servlet-name>
    <url-pattern>/Photo</url-pattern>
</servlet-mapping>

问题:

我收到以下异常:

java.io.IOException: Stream closed

在这条线上:

at app.controllers.PhotoServlet.doGet(PhotoServlet.java:94)
while ((length = input.read(buffer)) > 0) {

完整的异常:

java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at app.controllers.PhotoServlet.doGet(PhotoServlet.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

我想基本的代码流程如下所示:

try {
    Get connection, statement, resultset
    Use connection, statement, resultset
    Get inputstream of resultset
} finally {
    Close resultset, statement, connection
}

try {
    Get outputstream
    Use inputstream of resultset, outputstream
} finally {
    Close outputstream, inputstream of resultset
}

结束时ResultSet已经隐式关闭了InputStream。您的 JDBC 驱动程序似乎没有存储InputStream of the ResultSet完全在内存或临时存储中时ResultSet关闭了。也许 JDBC 驱动程序有点简单,或者设计不周全,或者图像太大而无法存储在内存中。谁知道。

我首先弄清楚您正在使用的 JDBC 驱动程序实现/版本,然后查阅其开发人员文档以了解可能能够更改/修复此行为的设置。如果您仍然无法弄清楚,那么您必须重新排列基本代码流程,如下所示:

try {
    Get connection, statement, resultset
    Use connection, statement, resultset
    try {
        Get inputstream of resultset, outputstream
        Use inputstream of resultset, outputstream
    } finally {
        Close outputstream, inputstream of resultset
    }
} finally {
    Close resultset, statement, connection
}

Or

try {
    Get connection, statement, resultset
    Use connection, statement, resultset
    Get inputstream of resultset
    Copy inputstream of resultset
} finally {
    Close resultset, statement, connection
}

try {
    Get outputstream
    Use copy of inputstream, outputstream
} finally {
    Close outputstream, copy of inputstream
}

第一种方法是最有效的,只是代码比较笨拙。第二种方法在复制到时内存效率低下ByteArrayOutputStream,或者复制到时性能低下FileOutputStream。如果图像大多很小并且不超过兆字节或其他东西,那么我只需将其复制到ByteArrayOutputStream.

InputStream input = null;
OutputStream output = null;

try {
    input = new BufferedInputStream(resultSet.getBinaryStream("columnName"), DEFAULT_BUFFER_SIZE);
    output = new ByteArrayOutputStream();
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

    for (int length; ((length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length);
    }
} finally {
    if (output != null) try { output.close(); } catch (IOException ignore) {}
    if (input != null) try { input.close(); } catch (IOException ignore) {}
}

Image image = new Image();
image.setPhoto(new ByteArrayInputStream(output.toByteArray()));
// ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java.io.IOException:流已关闭 的相关文章

随机推荐

  • 多目标和多类预测

    我对机器学习和张量流比较陌生 我想训练数据 以便可以进行 2 个目标和多个类别的预测 这是可以做的事情吗 我能够为 1 个目标实现该算法 但不知道如何为第二个目标实现该算法 数据集示例 一年中的某一天温度流量能见度 316 8 1 4 28
  • browser.tabs.sendMessage(): 错误:接收端不存在

    我尝试运行上面给出的示例代码tabs sendMessage MDN 页面 https developer mozilla org en US Add ons WebExtensions API tabs sendMessage 所以我的代
  • 设置和获取交集的 MySQL 字符串

    我有一个错误投影的数据库 其中在文本列中设置了 ID 例如 1 2 5 10 我需要获得以相同方式设置的两列的交集 我不喜欢使用 PHP 或其他脚本语言来完成它 我也不喜欢 MySQL 自定义函数 有没有办法获得由逗号分隔符字符串给出的两个
  • Spring Data REST:如何在一次调用中使用 Id 列表检索多个项目?

    我可以通过以下调用从 Spring Data REST 检索一本书籍 获取 书 id 现在 如果我知道两本书的 Id 并且想一次检索它们呢 应该打电话什么 我尝试了以下操作 但它返回的书籍与指定的书籍不同 GET book ids id1
  • 删除 EF4 中的实体而不加载整个实体

    我正在使用实体框架 4 并有以下设置和问题 我在 MySql 中有一个表 其中包含元数据字段和 blob 字段 使用所描述的表拆分技术here http blogs microsoft co il blogs gilf archive 20
  • Twitter 分享按钮不转发自定义文本

    我正在开发一个网站 为每个特定产品提供 Twitter 共享选项 我按照 Twitter API 说明进行推文共享 除了自定义文本显示之外 一切正常 例如 我希望用户像这样发推文 你觉得怎么样 我应该买这个吗 http url etc ht
  • 调整未知大小的张量流图像的大小

    我有一个张量流 UNet 风格的网络 目前我指定输入和目标图像如下 self inputTensors tf placeholder tf float32 None opt inputHeight opt inputWidth opt in
  • 如何从多个 python-flask 子进程收集普罗米修斯指标?

    我有 main 函数 它生成两个单独的子进程 这两个子流程共享指标 如何共享两个流程的指标并保持更新 这是我的片段 以供更多理解 from multiprocessing import Process import prometheus c
  • 检查字符串是否包含前导字母

    如何检查我的字符串是否包含前导字母 在 C 中很容易 但我在 SQL 中这样做 有办法检查吗 如果是这样 我该如何删除它 前任 MyString A1234 更新后的字符串 1234 Use UPDATE YOUR TABLE SET yo
  • 我可以在运行时展开包含 C# 文字表达式的字符串吗

    如果我有一个包含 C 字符串文字表达式的字符串 我可以在运行时 扩展 它吗 public void TestEvaluateString string Dummy EvalString Contains r n new line Debug
  • 过滤以从数组中排除元素

    尝试从数组中过滤一些条目 不能保证它们位于主数组中 因此我正在通过迭代进行测试 total alpha bravo charlie delta echo hide charlie echo pick for i in total if hi
  • 通过 API 中的 Dynamodb 代理服务发布新记录时出现 SerializationException

    我正进入 状态 type com amazon coral service SerializationException 作为邮递员和 API 网关测试控制台中的回复 尝试使用 API 代理服务将记录直接发布到 dynamodb 我指的是这
  • 当命令有空格时将命令输出检索到变量

    我在很多地方读到可以使用 Windows 批处理文件for获取命令的输出并将其放入变量中 如下所示 FOR F G IN foo command DO SET FOO G 伟大的 所以我的foo command实际上是C Program F
  • Python3错误:initial_value必须是str或None,带有StringIO

    在移植代码时python2 to 3 从 URL 读取时出现此错误 类型错误 initial value 必须是 str 或 None 而不是 bytes import urllib import json import gzip from
  • 如何保持 Google Dataproc master 运行?

    我在 Dataproc 上创建了一个集群 效果很好 但是 当集群空闲一段时间 约90分钟 后 主节点将自动停止 我创建的每个集群都会发生这种情况 我看到这里有一个类似的问题 继续运行 Dataproc 主节点 https stackover
  • 如何在 cmake Android Studio 中添加 cflag?

    如何在 Cmake 配置文件中添加 D FILE OFFSET BITS 64 我试图在 build gradle 中添加为 cflag 但它不起作用 externalNativeBuild cmake cppFlags cFlags D
  • 从浏览器链接打开 Play 商店应用

    From 这个帖子 https stackoverflow com questions 35430336 redirect users to itunes app store or google play store我能够创建一个功能 将用
  • Laravel 删除查询生成器

    在 Laravel 4 中Illuminate Database Query in a Builder class delete函数接受null as an id范围 这个函数的行为意味着如果我有类似的东西 DB table users g
  • 通过意图从另一个活动关闭活动

    我想从第一个活动开始 并且想有目的地关闭第一个活动 我试过了 但接收器不起作用 我的应用程序中有不同的接收器 所以我希望仅从 FirstReceiver 接收此意图 我该怎么做 public class First extends Acti
  • java.io.IOException:流已关闭

    对于多图像检索 我正在调用PhotoHelperServlet使用锚标记来获取 imageNames 多个图像 如下所示 PhotoHelperServlet获取姓名Images protected void doGet HttpServl