下面是一个用多线程下载文件的程序,其中资源地址是我在网上找了个Mp3的链接后复制过来的,运行程序,文件是下下来了,但跟正常下下来的文件比对发现,比正常下下来的文件要大,而且在播放时发现最后一两分钟的地方有空白的部分,也有重复播放的部分。请高手指点看看是什么问题。
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
/** 利用多线程下载文件的示例 */
public class MultiThreadDownloadTest {
public static void main(String[] args) throws IOException {
String urlStr = "http://mp3.baidu.com/j?j=2&url=http%3A%2F%2Fzhangmenshiting2.baidu.com%2Fdata2%2Fmusic%2F14953359%2F14953359.mp3%3Fxcode%3D8c319eb85ffb1883ea3e51c28627c0b9"; //资源地址
URL url = new URL(urlStr); //创建URL
URLConnection con = url.openConnection(); //建立连接
int contentLen = con.getContentLength(); //获得资源总长度
int threadQut = 10; //线程数
int subLen = contentLen / threadQut; //每个线程要下载的大小
int remainder = contentLen % threadQut; //余数
File destFile = new File("D:\\IOTest\\bjhyl.mp3"); //目标文件
/////创建并启动线程
for (int i = 0; i < threadQut; i++) {
int start = subLen * i; //开始位置
int end = start + subLen -1; //结束位置
if(i == threadQut - 1){ //最后一个线程的结束位置
end += remainder;
}
Thread t = new Thread(new DownloadRunnable(start, end, url, destFile));
t.start();
}
}
}
/** 线程下载类 */
class DownloadRunnable implements Runnable {
private final int start;
private final int end;
private final URL srcURL;
private final File destFile;
public static final int BUFFER_SIZE = 8192; //缓冲区大小
DownloadRunnable(int start,int end, URL srcURL, File destFile) {
this.start = start;
this.end = end;
this.srcURL = srcURL;
this.destFile = destFile;
}
public void run() {
System.out.println(Thread.currentThread().getName() + "启动...");
BufferedInputStream bis = null;
RandomAccessFile ras = null;
byte[] buf = new byte[BUFFER_SIZE];//创建一个缓冲区
URLConnection con = null;
try {
con = srcURL.openConnection(); //创建网络连接
//设置连接的请求头字段:获取资源数据的范围从start到end
con.setRequestProperty("Range", "bytes=" + start + "-" + end);
//网络连接中获取输入流并包装成缓冲流
bis = new BufferedInputStream(con.getInputStream());
ras = new RandomAccessFile(destFile, "rw"); //创建RandomAccessFile
ras.seek(start); //把文件指针移动到start位置
int len = -1; //读取到的字节数
while((len = bis.read(buf)) != -1){ //从网络中读取数据
ras.write(buf, 0, len); //用随机存取流写到目标文件
}
System.out.println(Thread.currentThread().getName() + "已经下载完毕");
}catch(IOException e){
e.printStackTrace();
}finally{
//关闭所有的IO流对象
if(ras != null){
try { ras.close();} catch (IOException e) { e.printStackTrace();}
}
if(bis != null){
try { bis.close();} catch (IOException e) { e.printStackTrace();}
}
}
}
|
|