[英]Read and Write large binary files with Java
因此,我有这段代码可以从磁盘(tar.gz,exe或dmg)读取正确的安装程序文件,并将其流式传输给用户(下面的代码)。 安装程序实际上是归档文件,可以将其提取并可以手动运行设置(这是特定于Windows的,需要安装Mac安装程序,也需要提取Unix安装程序)
InputStream in = null;
OutputStream out = null;
byte[] buffer = new byte[16384];
try {
String bundle = ServletRequestUtils.getRequiredStringParameter(request, "bundle");
String installerPath = constructFilePath(bundle);
File installer = new File(installerPath);
if(!installer.exists()){
logger.error("Cannot read installer file");
response.sendRedirect("/somewhere");
}else{
in = new FileInputStream(installer);
response.setContentType(getBundleContentType(bundle)); //application/octet-stream or application/x-gzip or application/x-apple-diskimage
response.setHeader("Pragma", "private");
response.setHeader("Cache-Control", "private, must-revalidate");
response.addHeader("Content-Disposition", "attachment;filename="+getBundleFileName(bundle)); //Setting new file name
out = new BufferedOutputStream(response.getOutputStream());
while((in.read(buffer)) != -1)
out.write(buffer);
}
} catch (Exception e) {
logger.error("Exception downloading installer file, reason: " + e);
response.sendRedirect("/somewhere");
} finally {
if(in != null){
in.close();
}
if(out != null){
out.flush();
out.close();
}
}
return null;
我将以Windows(.exe)安装程序为例。 以前,当我有重定向到http:///somepath/installer.exe的代码进行下载时,该文件将被下载,并且能够使用7zip提取文件,但是现在,当我尝试提取文件时使用7zip,我得到:
Cannot open file as archive.
但是,我可以双击.exe并成功完成安装。 我也可以使用winRAR提取它。
Unix安装程序也发生了同样的事情。 当我将其下载到Unix计算机并尝试将其解压缩时(通过右键单击“在此处提取”),我收到此错误:
gzip: stdin: decompression OK, trailing garbage ignored
/bin/gtar: Child returned status 2
/bin/gtar: Error is not recoverable: exiting now
但是,我可以使用“ ark”打开它并正确提取其内容。
我还应该指出,下载后文件的字节不匹配(下载的文件与文件系统上的文件相比,应该相同)。
我想念什么吗?
您可以尝试写入与读取的数据完全相同的数据:
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
这是因为您正在写整个缓冲区。
假设文件为16385字节。
第一个in.read(buffer)
将填满整个缓冲区并返回16384。然后,您将写入整个缓冲区。 第二次,它将读取一个字节,然后再次写入整个缓冲区。
有人击败了我,但我要补充一点,您可以使用IOUtils
来做到这一点...
http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html
例如IOUtils.copy(in, out)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.