-
2018-06-15 22:19:43
java实现高效文件下载
本文我们介绍几种方法下载文件。从基本JAVA IO 到 NIO包,也介绍第三方库的一些方法,如Async Http Client 和 Apache Commons IO.
最后我们还讨论在连接断开后如何恢复下载。使用java IO
下载文件最基本的方法是java IO,使用URL类打开待下载文件的连接。为有效读取文件,我们使用openStream() 方法获取 InputStream:
BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream())
当从InputStream读取文件时,强烈建议使用BufferedInputStream去包装InputStream,用于提升性能。
使用缓存可以提升性能。read方法每次读一个字节,每次方法调用意味着系统调用底层的文件系统。当JVM调用read()方法时,程序执行上下文将从用户模式切换到内核模式并返回。从性能的角度来看,这种上下文切换非常昂贵。当我们读取大量字节时,由于涉及大量上下文切换,应用程序性能将会很差。
为了读取URL的字节并写至本地文件,需要使用FileOutputStream 类的write方法:
try (BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) { byte dataBuffer[] = new byte[1024]; int bytesRead; while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { fileOutputStream.write(dataBuffer, 0, bytesRead); } } catch (IOException e) { // handle exception }
使用BufferedInputStream,read方法按照我们设置缓冲器大小读取文件。示例中我们设置一次读取1024字节,所以BufferedInputStream 是必要的。
上述示例代码冗长,幸运的是在Java7中Files类包含处理IO操作的助手方法。可以使用File.copy()方法从InputStream中读取所有字节,然后复制至本地文件:
InputStream in = new URL(FILE_URL).openStream(); Files.copy(in, Paths.get(FILE_NAME), StandardCopyOption.REPLACE_EXISTING);
上述代码可以正常工作,但缺点是字节被缓冲到内存中。Java为我们提供了NIO包,它有方法在两个通道之间直接传输字节,而无需缓冲。下面我们会详细讲解。
使用NIO
java NIO包提供了无缓冲情况下在两个通道之间直接传输字节的可能。
为了读来自URL的文件,需从URL流创建ReadableByteChannel :
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
从ReadableByteChannel 读取字节将被传输至FileChannel:
FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME); FileChannel fileChannel = fileOutputStream.getChannel();
然后使用transferFrom方法,从ReadableByteChannel 类下载来自URL的字节传输到FileChannel:
fileOutputStream.getChannel() .transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
transferTo() 和 transferFrom() 方法比简单使用缓存从流中读更有效。依据不同的底层操作系统,数据可以直接从文件系统缓存传输到我们的文件,而不必将任何字节复制到应用程序内存中。
在Linux和UNIX系统上,这些方法使用零拷贝技术,减少了内核模式和用户模式之间的上下文切换次数。
使用第三方库
上面我们已经使用java 核心功能实现从URL下载文件。当无需调整性能是,我们也可以利用第三方库轻松实现。举例,在实际场景中,需要实现异步下载,我们可以封装逻辑至Callable,下面看已有库实现。
Async HTTP Client
Async HTTP Client是使用Netty框架执行异步HTTP请求的流行库。我们使用它对URL文件执行GET请求并获取其内容。首先需要创建HTTP client:
AsyncHttpClient client = Dsl.asyncHttpClient();
下面内容放到FileOutputStream:
FileOutputStream stream = new FileOutputStream(FILE_NAME);
接下来,创建HTTP GET请求并注册AsyncCompletionHandler 处理器去处理下载内容:
client.prepareGet(FILE_URL).execute(new AsyncCompletionHandler<FileOutputStream>() { @Override public State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception { stream.getChannel().write(bodyPart.getBodyByteBuffer()); return State.CONTINUE; } @Override public FileOutputStream onCompleted(Response response) throws Exception { return stream; } })
上面我们覆盖了onBodyPartReceived() 方法。缺省实现是累加HTTP 接收块至ArrayList,这可能导致耗费高内存或下载大文件时OutOfMemory 异常。
代替累加每个HttpResponseBodyPart 至内存,我们使用FileChannel写字节至本地文件。getBodyByteBuffer()方法通过ByteBuffer访问bodyPart内容。ByteBuffers的优势是把内存分配到JVM堆之外,所以不会影响应用程序的内存。Apache Commons IO
另一个高可用的IO操作库是Apache Commons IO。我们从其Javadoc看到FileUtils实用类,用于一般的文件操作任务。从URL下载文件,仅需一行代码:
FileUtils.copyURLToFile( new URL(FILE_URL), new File(FILE_NAME), CONNECT_TIMEOUT, READ_TIMEOUT);
从性能角度看,与前面JAVA IO示例相同。底层代码使用相同的概念,从InputStream读取一些字节并将它们写入OutputStream。不同之处在于,URLConnection类在这里用于控制连接超时,这样下载就不会阻塞很长时间:
URLConnection connection = source.openConnection(); connection.setConnectTimeout(connectionTimeout); connection.setReadTimeout(readTimeout);
恢复下载
考虑到internet连接的不确定性,失败时我们可以重新下载文件,但不是再次从字节0位置下载文件。
让我们重写前面的第一个示例,以添加这个功能。我们首先要知道的是,我们可以使用HTTP HEAD方法从给定URL读取文件的大小,而无需实际下载它:
URL url = new URL(FILE_URL); HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setRequestMethod("HEAD"); long removeFileSize = httpConnection.getContentLengthLong();
现在我们有了文件内容的总大小,可以检查文件是否已下载了部分内容。如果是,我们将继续从磁盘上记录的最后一个字节开始下载:
long existingFileSize = outputFile.length(); if (existingFileSize < fileLength) { httpFileConnection.setRequestProperty( "Range", "bytes=" + existingFileSize + "-" + fileLength ); }
上述代码我们配置了URLConnection以在一定范围内请求文件内容。范围将从最后下载的字节位置开始,并以远程文件大小的字节长度为结束。
使用范围HEAD标识的另一种常见方法是通过设置不同的字节范围以块形式下载文件。例如,要下载2KB文件,我们可以使用范围0 - 1024和1024 - 2048。
与前节代码稍微不同的是设置FileOutputStream 方法append参数为true:
OutputStream os = new FileOutputStream(FILE_NAME, true);
在我们做了这个更改之后,其余的代码与我们前面看到的代码一样。
总结
在本文中,我们已经看到Java中从URL下载文件的几种实现方式。
最常见的实现是在执行读/写操作时使用缓冲区。这个实现即使对于大文件也是安全的,因为我们没有将整个文件加载到内存中。
我们还了解了如何使用Java NIO通道实现零拷贝下载。这很有用,因为它最小化了在读取和写入字节时执行的上下文切换的次数,并且通过使用直接缓冲区字节不会加载到应用程序内存中。另外,由于下载文件通常是通过HTTP完成的,我们也说明如何使用AsyncHttpClient库实现这一点。更多相关内容 -
Java大文件上传(1GB,图片,视频,Flash文件,音频文件)
2021-03-03 04:30:191GB以内的任何文档、图片、视频、Flash文件和音频文件都可以多文件无刷新批量上传。 1GB以内的任何文档、图片、视频、Flash文件和音频文件都可以多文件无刷新批量上传。 -
Java实现文件的上传下载
2017-10-09 12:59:47该代码是一个使用Java开发的上传下载的一个demo,一共有两种方法,第一种是使用最基础的IO流进行文件的上传,可以了解一下原理。第二种是使用apache的commons-IO包进行文件的上传,其实只要了解了这两种上传文件的... -
java实现文件重命名
2020-08-24 19:32:41主要为大家详细介绍了java实现文件重命名,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
java下载文件到指定路径(不打开窗口)
2019-03-01 09:38:28此文档记录的是通过java程序下载文件到指定路径的方法 -
java实现文件下载
2013-08-06 12:00:11java实现的文件上传下载,struts2实现的文件上传下载~! -
JavaAPI文档中文版
2018-05-23 17:17:19JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI... -
JAVA本地文件下载
2012-12-24 11:06:41JAVA代码,通过文件名及文件的路径(全路径)实现本地文件的下载。 -
java实现大文件下载(http方式)
2019-01-25 10:13:52java实现大文件下载,基于http方式,控件神马的就不说了。 思路:下载文件无非要读取文件然后写文件,主要这两个步骤,主要难点: 1.读文件,就是硬盘到内存的过程,由于jdk内存限制,不能读的太大。 2.写文件,...java实现大文件下载,基于http方式,控件神马的就不说了。
思路:下载文件无非要读取文件然后写文件,主要这两个步骤,主要难点:
1.读文件,就是硬盘到内存的过程,由于jdk内存限制,不能读的太大。
2.写文件,就是响应到浏览器端的过程,http协议是短链接,如果写文件太慢,时间过久,会造成浏览器死掉。知识点:
1.org.apache.http.impl.client.CloseableHttpClient 模拟httpClient客户端发送http请求,可以控制到请求文件的字节位置。 2.BufferedInputStream都熟悉,用它接受请求来的流信息缓存。 3.RandomAccessFile文件随机类,可以向文件写入指定位置的流信息。
基于以上信息,我的实现思路就是首先判断下载文件大小,配合多线程分割定制http请求数量和请求内容,响应到写入到RandomAccessFile指定位置中。在俗点就是大的http分割成一个个小的http请求,相当于每次请求一个网页。
废话不说,上代码。
DownLoadManagerTest类:
package xxxx; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.CountDownLatch; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.task.TaskExecutor; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * * 文件下载管理类 */ @RunWith(SpringJUnit4ClassRunner.class) @ActiveProfiles("test") @ContextConfiguration(locations={"classpath:test/applicationContext.xml"}) public class DownLoadManagerTest extends AbstractTransactionalJUnit4SpringContextTests{ private static final Logger LOGGER = LoggerFactory.getLogger(DownLoadManagerTest.class); /** * * 每个线程下载的字节数 */ private long unitSize = 1000 * 1024; @Autowired private TaskExecutor taskExecutor; private CloseableHttpClient httpClient; private Long starttimes; private Long endtimes; @Before public void setUp() throws Exception{ starttimes = System.currentTimeMillis(); System.out.println("测试开始...."); } @After public void tearDown() throws Exception{ endtimes = System.currentTimeMillis(); System.out.println("测试结束!!"); System.out.println("********************"); System.out.println("下载总耗时:"+(endtimes-starttimes)/1000+"s"); System.out.println("********************"); } public DownLoadManagerTest() { System.out.println("初始化测试类...."); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); httpClient = HttpClients.custom().setConnectionManager(cm).build(); } /** * * 启动多个线程下载文件 */ @Test public void doDownload() throws IOException { String remoteFileUrl="http://{host}:{port}/{project}/xx.xml"; String localPath="E://test//"; String fileName = new URL(remoteFileUrl).getFile(); System.out.println("远程文件名称:"+fileName); fileName = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length()).replace("%20", " "); System.out.println("本地文件名称:"+fileName); long fileSize = this.getRemoteFileSize(remoteFileUrl); this.createFile(localPath+System.currentTimeMillis()+fileName, fileSize); Long threadCount = (fileSize/unitSize)+(fileSize % unitSize!=0?1:0); long offset = 0; CountDownLatch end = new CountDownLatch(threadCount.intValue()); // 如果远程文件尺寸小于等于unitSize if (fileSize <= unitSize) { DownloadThreadTest downloadThread = new DownloadThreadTest(remoteFileUrl, localPath+fileName, offset, fileSize,end,httpClient); taskExecutor.execute(downloadThread); } else { // 如果远程文件尺寸大于unitSize for (int i = 1; i < threadCount; i++) { DownloadThreadTest downloadThread = new DownloadThreadTest( remoteFileUrl, localPath+fileName, offset, unitSize,end,httpClient); taskExecutor.execute(downloadThread); offset = offset + unitSize; } // 如果不能整除,则需要再创建一个线程下载剩余字节 if (fileSize % unitSize != 0) { DownloadThreadTest downloadThread = new DownloadThreadTest(remoteFileUrl, localPath+fileName, offset, fileSize - unitSize * (threadCount-1),end,httpClient); taskExecutor.execute(downloadThread); } } try { end.await(); } catch (InterruptedException e) { LOGGER.error("DownLoadManager exception msg:{}",ExceptionUtils.getFullStackTrace(e)); e.printStackTrace(); } // System.out.println("111111"); LOGGER.debug("下载完成!{} ",localPath+fileName); //return localPath+fileName; } /** * * 获取远程文件尺寸 */ private long getRemoteFileSize(String remoteFileUrl) throws IOException { long fileSize = 0; HttpURLConnection httpConnection = (HttpURLConnection) new URL( remoteFileUrl).openConnection(); httpConnection.setRequestMethod("HEAD"); int responseCode = httpConnection.getResponseCode(); if (responseCode >= 400) { LOGGER.debug("Web服务器响应错误!"); return 0; } String sHeader; for (int i = 1;; i++) { sHeader = httpConnection.getHeaderFieldKey(i); if (sHeader != null && sHeader.equals("Content-Length")) { System.out.println("文件大小ContentLength:" + httpConnection.getContentLength()); fileSize = Long.parseLong(httpConnection .getHeaderField(sHeader)); break; } } return fileSize; } /** * * 创建指定大小的文件 */ private void createFile(String fileName, long fileSize) throws IOException { File newFile = new File(fileName); RandomAccessFile raf = new RandomAccessFile(newFile, "rw"); raf.setLength(fileSize); raf.close(); } public TaskExecutor getTaskExecutor() { return taskExecutor; } public void setTaskExecutor(TaskExecutor taskExecutor) { this.taskExecutor = taskExecutor; } }
DownloadThreadTest类:
package xxxx; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.concurrent.CountDownLatch; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * 负责文件下载的类 */ public class DownloadThreadTest extends Thread { private static final Logger LOGGER = LoggerFactory .getLogger(DownloadThreadTest.class); /** * * 待下载的文件 */ private String url = null; /** * * 本地文件名 */ private String fileName = null; /** * * 偏移量 */ private long offset = 0; /** * * 分配给本线程的下载字节数 */ private long length = 0; private CountDownLatch end; private CloseableHttpClient httpClient; private HttpContext context; /** * * @param url 下载文件地址 * * @param fileName 另存文件名 * * @param offset 本线程下载偏移量 * * @param length 本线程下载长度 * * @author Angus.wang * * */ public DownloadThreadTest(String url, String file, long offset, long length, CountDownLatch end, CloseableHttpClient httpClient) { this.url = url; this.fileName = file; this.offset = offset; this.length = length; this.end = end; this.httpClient = httpClient; this.context = new BasicHttpContext(); LOGGER.debug("偏移量=" + offset + ";字节数=" + length); } public void run() { try { HttpGet httpGet = new HttpGet(this.url); httpGet.addHeader("Range", "bytes=" + this.offset + "-" + (this.offset + this.length - 1)); CloseableHttpResponse response = httpClient.execute(httpGet, context); BufferedInputStream bis = new BufferedInputStream(response .getEntity().getContent()); byte[] buff = new byte[1024]; int bytesRead; File newFile = new File(fileName); RandomAccessFile raf = new RandomAccessFile(newFile, "rw"); while ((bytesRead = bis.read(buff, 0, buff.length)) != -1) { raf.seek(this.offset); raf.write(buff, 0, bytesRead); this.offset = this.offset + bytesRead; } raf.close(); bis.close(); } catch (ClientProtocolException e) { LOGGER.error("DownloadThread exception msg:{}",ExceptionUtils.getFullStackTrace(e)); } catch (IOException e) { LOGGER.error("DownloadThread exception msg:{}",ExceptionUtils.getFullStackTrace(e)); } finally { end.countDown(); LOGGER.info(end.getCount() + " is go on!"); System.out.println(end.getCount() + " is go on!"); } } }
application.xml
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 线程池活跃的线程数 --> <property name="corePoolSize" value="5" /> <!-- 线程池最大活跃的线程数 --> <property name="maxPoolSize" value="10" /> <!-- 队列的最大容量 --> <property name="queueCapacity" value="600" /> </bean> <bean id="downLoadManager" class="xx.DownLoadManagerTest"> <property name="taskExecutor" ref="taskExecutor" /> </bean>
测试运行,500M,我这网速得半个小时左右。要想下载更大的文件,只要jdk内存够大,就无限更改队列最大容量吧。
如果不同意见,欢迎各位大神指正。
-
java 实现文件下载进度条
2020-09-02 17:16:09计算不同用户的下载进度 import java.io.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; public class ProgressBarThread implements Runnable { private ArrayList<...计算不同用户的下载进度
import java.io.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; public class ProgressBarThread implements Runnable { private ArrayList<Integer> proList = new ArrayList<Integer>(); private int progress;//当前进度 private int totalSize;//下载文法总大小 private boolean run = true; private int showProgress; public static HashMap<String, Integer> progressMap = new HashMap<>();//各用户的下载进度 public static HashMap<String, Boolean> executeStatusMap = new HashMap<>();//各用户是否下载中 private Long fileId; private String token; public ProgressBarThread(int totalSize, Long fileId, String token) { this.totalSize = totalSize; this.fileId = fileId; this.token = token; //创建进度条时,将指定用户的执行状态改为true executeStatusMap.put(token, true); } /** * @param progress 进度 */ public void updateProgress(int progress) { synchronized (this.proList) { if (this.run) { this.proList.add(progress); this.proList.notify(); } } } public void finish() { this.run = false; //关闭进度条 } @Override public void run() { synchronized (this.proList) { try { while (this.run) { if (this.proList.size() == 0) { this.proList.wait(); } synchronized (proList) { this.progress += this.proList.remove(0); //更新进度条 showProgress = (int) ((new BigDecimal((float) this.progress / this.totalSize).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()) * 100); progressMap.put(token + fileId, showProgress); if (showProgress == 100) { //进度100%时将用户的执行状态改为false executeStatusMap.put(token, false); } System.err.println("当前进度:"+showProgress+"%"); } } System.err.println("下载完成"); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { try { File file = new File("C:/Users/mfy/Desktop/蜜雪冰城.pdf"); FileInputStream fis = new FileInputStream(file); FileOutputStream fos = new FileOutputStream("D:/nms/img/蜜雪冰城.pdf"); ProgressBarThread pbt = new ProgressBarThread((int) file.length(), 1L, "000001");//创建进度条 new Thread(pbt).start();//开启线程,刷新进度条 byte[] buf = new byte[1024]; int size = 0; while ((size = fis.read(buf)) > -1) {//循环读取 fos.write(buf, 0, size); pbt.updateProgress(size);//写完一次,更新进度条 } pbt.finish();//文件读取完成,关闭进度条 fos.flush(); fos.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
获取获取下载进度,可以通过webSocket推送,也可以前端定时调用
public HzRestResult getProgress(String fileId, HttpServletRequest request) { String token = request.getHeader("token"); Integer progress = ProgressBarThread.progressMap.get(token + fileId); if (progress == null) { return HzRestResult.getFailed("该任务不存在!"); } if(progress.equals(100)){ //进度100%时清除指定map ProgressBarThread.progressMap.remove(token + fileId); } JSONObject jsonObject = new JSONObject(); jsonObject.put("fileId", fileId); jsonObject.put("token", token); jsonObject.put("progress", progress); return HzRestResult.getSuccess(jsonObject); }
-
Java实现文件与图片的上传下载---3种方式
2017-01-12 14:40:49Java实现文件与图片的上传下载---3种方式 1)JSP+Servlet; 2)smartUpload; 3)FileUpload; -
Java实现文件下载功能
2012-02-25 18:03:13Java实现文件下载功能,以WORD文档方式展现给用户看。 -
java使用HttpClient通过url下载文件到本地
2016-08-17 12:01:59Eclipse下完整的java程序,包含HttpClient的全部jar包。通过java类文件,实现通过链接将文件下载本地 -
java的API接口文档模板
2021-01-12 10:16:44java初学者 -
JAVA8API-官方文档下载-中文版
2017-08-13 00:55:14javaAPI 官方文档 中文版 良心! -
Java下载文件的几种方式
2021-03-05 19:04:411.以流的方式下载.public HttpServletResponse download(String path, HttpServletResponse response) {try {// path是指欲下载的文件的路径。File file = new File(path);// 取得文件名。String filename = file....1.以流的方式下载.
public HttpServletResponse download(String path, HttpServletResponse response) {
try {
// path是指欲下载的文件的路径。
File file = new File(path);
// 取得文件名。
String filename = file.getName();
// 取得文件的后缀名。
String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return response;
}
2.下载本地文件
public void downloadLocal(HttpServletResponse response) throws FileNotFoundException {
// 下载本地文件
String fileName = "Operator.doc".toString(); // 文件的默认保存名
// 读到流中
InputStream inStream = new FileInputStream("c:/Operator.doc");// 文件的存放路径
// 设置输出的格式
response.reset();
response.setContentType("bin");
response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
// 循环取出流中的数据
byte[] b = new byte[100];
int len;
try {
while ((len = inStream.read(b)) > 0)
response.getOutputStream().write(b, 0, len);
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
3.下载网络文件
public void downloadNet(HttpServletResponse response) throws MalformedURLException {
// 下载网络文件
int bytesum = 0;
int byteread = 0;
URL url = new URL("windine.blogdriver.com/logo.gif");
try {
URLConnection conn = url.openConnection();
InputStream inStream = conn.getInputStream();
FileOutputStream fs = new FileOutputStream("c:/abc.gif");
byte[] buffer = new byte[1204];
int length;
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
System.out.println(bytesum);
fs.write(buffer, 0, byteread);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4.支持在线打开的方式
public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {
File f = new File(filePath);
if (!f.exists()) {
response.sendError(404, "File not found!");
return;
}
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[1024];
int len = 0;
response.reset(); // 非常重要
if (isOnLine) { // 在线打开方式
URL u = new URL("file:///" + filePath);
response.setContentType(u.openConnection().getContentType());
response.setHeader("Content-Disposition", "inline; filename=" + f.getName());
// 文件名应该编码成UTF-8
} else { // 纯下载方式
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());
}
OutputStream out = response.getOutputStream();
while ((len = br.read(buf)) > 0)
out.write(buf, 0, len);
br.close();
out.close();
}
喜欢本文的朋友们,欢迎关注微信公众号“Java面试达人”,收看更多精彩内容
-
java大文件分块上传断点续传demo
2017-09-29 10:35:05完整的java大文件分块上传支持断点续传,包含jar包,可以直接导入eclipse使用。 -
java response 下载文件方法
2012-08-08 17:22:55java response 下载文件方法。使用流下载文件。 -
Java Web文件下载,解决了使用IE11下载文件时所出现的乱码问题
2014-09-02 09:19:53本工程用于研究Java Web文件下载 本工程编码方式:UTF-8 说明:本工程下载功能解决了使用IE11下载文件时所出现的乱码问题 -
Java实现的小型文件管理系统
2019-11-02 00:31:50文件批量处理用(Eclipse)Java实现,模块为了方便管理文件而设计,通过本模块可以快速地实现文件的批量复制、批量删除、批量重命名、文件分类等。内含设计文档,包括使用说明。还有打包好的可运行的jar文件。 -
ajax实现java文件下载
2011-05-12 15:48:16用ajax实现的java文件打包下载。可以输入扩展名选择文件下载。 -
JAVA 批量下载文件
2019-07-04 14:47:07最近项目有个需求,用户想对挂有附件的数据记录 实现一键下载全部附件(目前项目仅支持每次点击单条记录进行附件下载),下面记录我实现的解决方案。 项目框架基于SSM service业务实现层(impl): //获取配置的... -
java访问https网址下载文件
2013-10-18 20:01:05java访问https网址下载文件,当网页需要下载证书的时候,代码和操作步骤齐全。 -
java实现文件下载,并弹出保存对话框(Excel)
2013-12-04 10:54:27java实现文件下载,并弹出保存对话框(Excel) -
JAVA API官方文档 中文版
2018-04-21 15:49:55JAVA API官方文档 中文版 ~打酱油~打酱油~打酱油~打酱油 -
JAVA_API_中文版帮助文档
2018-01-24 19:32:50java jdk1.8 api中文版帮助文档可以很好地帮助java初学者学习关于类,框架,包,系统api的资源介绍 -
Java实现文件下载Zip压缩
2021-03-25 16:24:49这里实现只是模式本地文件下载Zip,响应的客户端下载 实现思路 创建一个临时文件zip 构建一个Zip文件输出流(临时文件Zip) 从服务读取文件流放入Zip文件输出流 把临时文件Zip写入OutputStream 关闭资源 1. ... -
java jdk 8 帮助文档 中文 文档 chm 谷歌翻译
2017-04-02 16:21:35JDK1.8 API 中文谷歌翻译版 java帮助文档 JDK API java 帮助文档 谷歌翻译 JDK1.8 API 中文 谷歌翻译版 java帮助文档 Java最新帮助文档 本帮助文档是使用谷歌翻译,非人工翻译。准确性不能保证,请与英文版配合使用 ... -
java读取超大文本文件
2011-12-16 23:17:40java读取超大文本文件,java读取超大文本文件,java读取超大文本文件,java读取超大文本文件 -
java 实现 word 文档的在线预览
2018-03-02 09:41:35java 实现 word 文档的在线预览,资源包含代码和jar包,下载放入项目既可以使用