Vaadin 上传文件流没有关闭?
Vaadin Upload filestream no close?
Vaadin 7.6.2
来自这个文档,来自这个代码示例:
https://vaadin.com/docs/-/part/framework/components/components-upload.html
// Show uploaded file in this placeholder
final Embedded image = new Embedded("Uploaded Image");
image.setVisible(false);
// Implement both receiver that saves upload in a file and
// listener for successful upload
class ImageUploader implements Receiver, SucceededListener {
public File file;
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Stream to write to
try {
// Open the file for writing.
file = new File("/tmp/uploads/" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
new Notification("Could not open file<br/>",
e.getMessage(),
Notification.Type.ERROR_MESSAGE)
.show(Page.getCurrent());
return null;
}
return fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
// Show the uploaded file in the image viewer
image.setVisible(true);
image.setSource(new FileResource(file));
}
};
ImageUploader receiver = new ImageUploader();
// Create the upload with a caption and set receiver later
Upload upload = new Upload("Upload Image Here", receiver);
upload.setButtonCaption("Start Upload");
upload.addSucceededListener(receiver);
// Put the components in a panel
Panel panel = new Panel("Cool Image Storage");
Layout panelContent = new VerticalLayout();
panelContent.addComponents(upload, image);
panel.setContent(panelContent);
关于这个我有几个问题:
- 为什么没有
fos.close()
任何地方(在 finally
块中)?
- 为什么
OutputStream
从方法返回?特别是当 receiver
被传递给一个监听器时?监听器是否正在关闭流?
- 在哪里关闭流?
如果您查看 sources,您会看到:
- Why no
fos.close()
anywhere (in finally
block)?
因为关闭输出流不是由你决定的。该框架将处理读取它接收到的数据,将其写入文件并关闭流(即使出现问题)。这发生在 FileUploadHandler
in the streamToReceiver()
method (line 529 in the current version).
- Why in the world is
OutputStream
returned from the method? Especially when the receiver
is being passed into a Listener
? Is the Listener closing the stream?
因为 Receiver
的唯一目的是告诉框架应该将接收到的数据写入何处。来自文档:
/**
* Interface that must be implemented by the upload receivers to provide the
* Upload component an output stream to write the uploaded data.
*
* @author Vaadin Ltd.
* @since 3.0
*/
为了进一步阐明 receiver
被传递到 Listener
的混乱:它不是。 ImageUploader
实现了两者
Receiver
- 提供应该写入内容的输出流
SucceededListener
- 上传成功完成后收到通知
因此,相同的 ImageUploader
实例被传递到 Upload
组件的构造函数中,它将被用作 Receiver
,并在 addSucceededListener()
方法中传递它将用作……你猜对了,SucceededListener
。大多数人(可能?!)更喜欢在同一个 class 中实现所有这些接口,但如果您愿意,您可以选择在它们自己的 class 中实现每个功能,然后传递一个每个方法的适当实例。
- Where do I close the stream?
你不需要,正如第 1 点所述,上传完成后框架会为你关闭它。同时,你可以去喝杯啤酒:-)
Vaadin 7.6.2
来自这个文档,来自这个代码示例: https://vaadin.com/docs/-/part/framework/components/components-upload.html
// Show uploaded file in this placeholder
final Embedded image = new Embedded("Uploaded Image");
image.setVisible(false);
// Implement both receiver that saves upload in a file and
// listener for successful upload
class ImageUploader implements Receiver, SucceededListener {
public File file;
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Stream to write to
try {
// Open the file for writing.
file = new File("/tmp/uploads/" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
new Notification("Could not open file<br/>",
e.getMessage(),
Notification.Type.ERROR_MESSAGE)
.show(Page.getCurrent());
return null;
}
return fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
// Show the uploaded file in the image viewer
image.setVisible(true);
image.setSource(new FileResource(file));
}
};
ImageUploader receiver = new ImageUploader();
// Create the upload with a caption and set receiver later
Upload upload = new Upload("Upload Image Here", receiver);
upload.setButtonCaption("Start Upload");
upload.addSucceededListener(receiver);
// Put the components in a panel
Panel panel = new Panel("Cool Image Storage");
Layout panelContent = new VerticalLayout();
panelContent.addComponents(upload, image);
panel.setContent(panelContent);
关于这个我有几个问题:
- 为什么没有
fos.close()
任何地方(在finally
块中)? - 为什么
OutputStream
从方法返回?特别是当receiver
被传递给一个监听器时?监听器是否正在关闭流? - 在哪里关闭流?
如果您查看 sources,您会看到:
- Why no
fos.close()
anywhere (infinally
block)?
因为关闭输出流不是由你决定的。该框架将处理读取它接收到的数据,将其写入文件并关闭流(即使出现问题)。这发生在 FileUploadHandler
in the streamToReceiver()
method (line 529 in the current version).
- Why in the world is
OutputStream
returned from the method? Especially when thereceiver
is being passed into aListener
? Is the Listener closing the stream?
因为 Receiver
的唯一目的是告诉框架应该将接收到的数据写入何处。来自文档:
/**
* Interface that must be implemented by the upload receivers to provide the
* Upload component an output stream to write the uploaded data.
*
* @author Vaadin Ltd.
* @since 3.0
*/
为了进一步阐明 receiver
被传递到 Listener
的混乱:它不是。 ImageUploader
实现了两者
Receiver
- 提供应该写入内容的输出流SucceededListener
- 上传成功完成后收到通知
因此,相同的 ImageUploader
实例被传递到 Upload
组件的构造函数中,它将被用作 Receiver
,并在 addSucceededListener()
方法中传递它将用作……你猜对了,SucceededListener
。大多数人(可能?!)更喜欢在同一个 class 中实现所有这些接口,但如果您愿意,您可以选择在它们自己的 class 中实现每个功能,然后传递一个每个方法的适当实例。
- Where do I close the stream?
你不需要,正如第 1 点所述,上传完成后框架会为你关闭它。同时,你可以去喝杯啤酒:-)