什么时候关闭InputStream?

问题描述

我正在使用Vaadin,我需要创建一个链接来下载PDF文件。 但是,我需要关闭InputStream。但是,如果我在用户单击以下载PDF文件时将其关闭,则会关闭它并抛出异常。正确的关闭位置在哪里?

File file = new File("f:\\10041328370.pdf");
Anchor a;
try{    
    InputStream is= new FileInputStream(file);          
    StreamResource res = new StreamResource("10041328370.pdf",() -> is );
    
    a = new Anchor(res,"click here to download");
    a.getElement().setAttribute("download","downloaded-other-name.pdf");
    add(a);
    
    is.close(); //if close here,when the user to click in the anchor,we will get the error: Stream Closed.                

} catch (IOException e) {
    throw new RuntimeException(e.getMessage);
}

解决方法

您不需要关闭InputStream。提供StreamResourceInputStreamFactory会调用您的工厂来创建新的输入流,并将始终为您关闭输入流(请使用 try-with-resources 参见{{11}} )。

但是这里的问题是,您正在提供一个“常数”工厂,该工厂总是返回相同的IS。因此,第二次下载现在将在封闭的IS上失败。实际上,您应该像实际工厂一样实施工厂,并始终返回新的IS。

例如

com.vaadin.flow.server.StreamResource.Pipe#accept
,

您可能应该在try catch语句之外初始化InputStream。流的作用域仅在try块内部,因此不可能在需要的地方(该块之外)关闭它,因为它不再存在。初始化它,也许在初始化文件之后:

input_numpy_array=np.array([1])
model = keras.models.Sequential()
input_layer = keras.layers.Input(shape=input_numpy_array.shape,name='input',batch_size=1)
model.add(input_layer)
output_layer = keras.layers.Dense(1,use_bias=False,name='output',batch_size=1)
model.add(output_layer)
print(model.summary())

最好也移动StreamResource。

编辑:要回答您的问题,与关闭流的位置无关,而与打开流的位置有关。在完成输入后将其关闭。