【发布时间】: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