读书人

Java学习 之 多线程上载文件【源码】

发布时间: 2012-08-10 12:19:33 作者: rapoo

Java学习 之 多线程下载文件【源码】

负责下载的线程:

import java.io.IOException;  import java.io.InputStream;  import java.io.RandomAccessFile;      public class DownloadThread extends Thread {            // 定义字节数组(用于取水的那个竹筒)的长度      private final int BUFF_LEN = 100;      // 定义下载的起始点      private long start;      // 定义下载的结束点      private long end;      // 下载资源对应的输入流      private InputStream inputStream;      // 下载资源对应的输出流      private RandomAccessFile randomAccessFile;            // 构造器:传入起始下载点,结束下载点,输入流,输出流      public DownloadThread (long start,long end,InputStream inputStream,RandomAccessFile randomAccessFile) {          // 打印一下该线程的起始下载点和结束下载点的位置信息          System.out.println(start+" >------> "+end);          this.start = start;          this.end = end;          this.inputStream = inputStream;          this.randomAccessFile = randomAccessFile;      }            @Override      public void run() {          try {              // 记录指针向前移动start个字符              inputStream.skip(start);              // 记录指针定位到start位置处              randomAccessFile.seek(start);              // 定义读取输入流内容的缓存数组(竹筒)              byte[] buff = new byte[BUFF_LEN];              // 本线程负责下载的资源大小              long contentLen = end - start;              // 定义最多需要几次就可以完成本线程的下载任务,方便控制线程的退出              long readMaxTimes = contentLen/BUFF_LEN + 4;              // 实际读取的字节数              int reallyReadCount = 0;              for (int i = 0; i < readMaxTimes; i++) {                  // 读取数据                  reallyReadCount = inputStream.read(buff);                  // 如果读取的字节数小于0,说明读取完毕,则退出循环                  if (reallyReadCount < 0) {                      break;                  }                  // 写入数据                  randomAccessFile.write(buff, 0, reallyReadCount);              }          } catch (IOException e) {              e.printStackTrace();          } finally {              // 使用finally块来关闭当前线程的输入流和输出流                  try {                  if (inputStream != null) {                      inputStream.close();                  }                  if (randomAccessFile != null) {                      randomAccessFile.close();                  }              } catch (IOException e) {                  e.printStackTrace();              }          }      }            }  

?

传入Url地址,开启下载:

import java.io.IOException;  import java.io.InputStream;  import java.io.RandomAccessFile;  import java.net.MalformedURLException;  import java.net.URL;  import java.net.URLConnection;    public class MultiDownload {            public static void main(String[] args) {          // 定义开启的线程数          final int DOWNLOAD_THREAD_NUM = 4;          // 定义下载文件的文件名,包括后缀          final String OUTPUT_FILE_NAME = "baidu.gif";          // 定义一个DOWNLOAD_THREAD_NUM大小的输入流数组          InputStream[] inArrays = new InputStream[DOWNLOAD_THREAD_NUM];          // 定义一个DOWNLOAD_THREAD_NUM大小的输出流数组          RandomAccessFile[] outArrays = new RandomAccessFile[DOWNLOAD_THREAD_NUM];                    try {              // 创建一个URL对象,参数是我们要下载的资源的地址              URL downloadUrl = new URL("http://www.baidu.com/img/baidu_sylogo1.gif");              // 以该URL对象打开第一个输入流              inArrays[0] = downloadUrl.openStream();              // 获取该网络资源文件的长度              long fileLength = getFileLength(downloadUrl);              // 做一个打印              System.out.println("该网络资源文件的大小:"+fileLength);              // 以输出的文件名创建第一个输出流对象,模式是可读,可写              outArrays[0] = new RandomAccessFile(OUTPUT_FILE_NAME, "rw");              // 创建一个与下载资源文件相同大小的空文件              for (int i = 0; i < fileLength; i++) {                  outArrays[0].write(0);              }              // 计算每个线程应该下载的字节数              long everyThreadDownloadSize = fileLength/DOWNLOAD_THREAD_NUM;              // 计算整个下载资源整除后剩下的余数              long otherDownloadSize = fileLength%DOWNLOAD_THREAD_NUM;              // 启动各个线程下载各自规定的读取长度的资源              for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) {                  // 刚才只初始化了第一个输入流和输出流对象,初始化剩下的输入流和输出流对象                  if (i != 0) {                      inArrays[i] = downloadUrl.openStream();                      outArrays[i] = new RandomAccessFile(OUTPUT_FILE_NAME, "rw");                  }                  // 独立配置最后一个线程的下载参数(该线程负责下载整除后余下的资源)                  if (i == DOWNLOAD_THREAD_NUM -1) {                      new DownloadThread(i*everyThreadDownloadSize, (i+1)*everyThreadDownloadSize+otherDownloadSize, inArrays[i], outArrays[i]);                  } else {                      // 配置前几个线程的下载参数                      new DownloadThread(i*everyThreadDownloadSize, (i+1)*everyThreadDownloadSize, inArrays[i], outArrays[i]);                  }              }          } catch (MalformedURLException e) {              e.printStackTrace();          } catch (IOException e) {              e.printStackTrace();          }                          }            // 根据URL获取该URL所指向的资源文件的长度      private static long getFileLength(URL url) throws IOException{          long length = 0;          URLConnection urlConnection = url.openConnection();          long size = urlConnection.getContentLength();          length = size;          return length;      }  }  

?

转自:http://emmet1988.iteye.com/blog/1065251

读书人网 >移动开发

热点推荐