Ali*_*han 3 java io zip multithreading
我尝试开发类似 dropbox(非常基本的)的东西。下载一个文件,这真的很容易。只需使用servletoutputstream。我想要的是:当客户端询问我多个文件时,我在服务器端压缩文件然后发送给用户。但是如果文件很大,压缩它们并发送给用户需要太多次。
有没有办法在压缩文件时发送文件?
谢谢你的帮助。
用于 ZIP 文件的部分 Java API 实际上旨在提供“动态”压缩。这一切都非常适合 java.io API 和 servlet API,这意味着这甚至......有点简单(不需要多线程 - 即使出于性能原因,因为通常您的 CPU 在 ZIPping 时可能比您的网络更快将在发送内容)。
您将与之交互的部分是ZipOutputStream. 它是一个FilterOutputStream(这意味着它旨在包装一个outputstream已经存在的 - 在您的情况下,这将是响应的OutputStream),并将使用 ZIP 压缩压缩您发送的每个字节。
所以,假设你有一个 get 请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Your code to handle the request
List<YourFileObject> responseFiles = ... // Whatever you need to do
// We declare that the response will contain raw bytes
response.setContentType("application/octet-stream");
// We open a ZIP output stream
try (ZipOutputStream zipStream = new ZipOutputStream(response.getOutputStream()) {// This is Java 7, but not that different from java 6
// We need to loop over each files you want to send
for(YourFileObject fileToSend : responseFiles) {
// We give a name to the file
zipStream.putNextEntry(new ZipEntry(fileToSend.getName()));
// and we copy its content
copy(fileToSend, zipStream);
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您应该进行适当的异常处理。不过有几个快速说明:
IllegalStateException无论如何,如果不这样做,您可能会得到一个)putNextEntry它时都会自行关闭前一个(如果需要)ZipOutputStream一旦所有内容都写入它,它就会关闭。copy这里的方法正是您用来将所有字节从原始文件传输到输出流的方法,它没有任何特定于 ZIP 的内容。就打电话outputStream.write(byte[] bytes)。**编辑:** 澄清...
例如,给定YourFileType具有以下方法的 a :
public interface YourFileType {
public byte[] getContent();
public InputStream getContentAsStream();
}
Run Code Online (Sandbox Code Playgroud)
然后复制方法可能看起来像(这都是非常基本的Java IO,您可以使用诸如commons io之类的库来不重新发明轮子......)
public void copy(YourFileType file, OutputStream os) throws IOException {
os.write(file.getContent());
}
Run Code Online (Sandbox Code Playgroud)
或者,对于完整的流媒体实现:
public void copy(YourFileType file, OutputStream os) throws IOException {
try (InputStream fileContent = file.getContentAsStream()) {
byte[] buffer = new byte[4096]; // 4096 is kind of a magic number
int readBytesCount = 0;
while((readBytesCount = fileContent.read(buffer)) >= 0) {
os.write(buffer, 0, readBytesCount);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用这种实现,您的客户端几乎在您开始写入时就开始接收响应ZIPOutputStream(唯一的延迟是内部缓冲区的延迟),这意味着它不应超时(除非您花费太长时间构建要发送的内容) - 但这不是 ZIPping 部分的错误)。
| 归档时间: |
|
| 查看次数: |
1848 次 |
| 最近记录: |