【问题标题】:InputStream read method blocking while reading the PDF读取 PDF 时 InputStream 读取方法阻塞
【发布时间】:2022-01-08 08:10:38
【问题描述】:

我在 servlet 中使用以下代码在应用程序中读取和写入 PDF,但在读取某些字节后,某些 PDF 的 read() 方法会被阻止:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    InputStream is = null;
    OutputStream oos = null;
    try {
         String pdfPath = (String) request.getSession().getAttribute("viewPdfPath");
         
         File file=new File(pdfPath);
         
         oos = response.getOutputStream();
         response.setContentType("application/pdf");
         byte[] buf = new byte[8192];
    
         is= new FileInputStream(file);
         int c = 0;
         while ((c = is.read(buf, 0, buf.length)) > 0) { **//blocking after reading some bytes**
             oos.write(buf, 0, c);
             oos.flush();
         }
    
         oos.flush();
     } catch (FileNotFoundException e) {
            e.printStackTrace();
    }catch(Exception e){
        e.printStackTrace();
    } finally {
        if(oos != null)
            oos.close();
        if(is != null)
            is.close();
    }
}

当作为独立 java 类的一部分从终端执行时,上述代码在当前托管应用程序的同一 Linux 服务器上成功读取同一 PDF 的所有字节。

为什么 InputStream read() 方法作为应用程序的一部分被阻塞,但从同一 Linux 服务器上执行的相同代码作为独立 java 类的一部分却成功读取而没有阻塞?

【问题讨论】:

  • 与您的问题无关,但我强烈建议您学习如何使用try-with-resources 来简化代码并防止当前代码中可能出现的资源泄漏。
  • 1 显着区别:“独立 java”应用程序听起来不像“多线程”!?当您(意外)“按两次按钮”时会发生什么!? (在同一个“会话”中......不改变viewPdfPath)......将有两个线程试图从同一个文件中读取!
  • 每次调用doGet 方法时,它都会在单独的线程中运行。尝试在您的独立 Java 程序中创建多个线程,其中每个线程都尝试读取同一个 PDF 文件并查看是否会阻塞。
  • @xerx593 为什么concurrent reads of the same file 会导致无限期阻塞?
  • 使用Files.copy(Path.of(pdfPath), oos) 而不是那些冗长的代码。您如何确认 pdfPath 读取已被阻止?获取应用服务器的线程转储 (kill -QUIT pid) 并查看同一服务器的打开文件句柄 (lsof |grep pid)。

标签: java inputstream


【解决方案1】:

根据JavadocFileInputStream::read是一个阻塞操作:

从此输入流中读取最多 len 个字节的数据到一个字节数组中。如果 len 不为零,则该方法会阻塞,直到某些输入可用

当从同一台机器本地读取文件时,读取操作可能会很快完成,但这并不意味着理论上它不会阻塞等待操作系统、磁盘等几毫秒。远程机器,更有可能是阻塞时间长到让你注意到。

【讨论】:

  • 我认为OP意味着它完全阻塞,无限期等待,而不仅仅是暂时阻塞以获取更多数据。
猜你喜欢
  • 2010-10-11
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
相关资源
最近更新 更多