上次分片下载的bug

mac2025-05-21  58

package com.dhcc.thread; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; public class TestIo { String mubiao; String dizhi; int startIndex; int endIndex; int threadNnum; public TestIo(String mubiao, String dizhi, int threadNnum) { super(); this.mubiao = mubiao; this.dizhi = dizhi; this.threadNnum = threadNnum; } public void copy() throws IOException { for (int id = 0; id < threadNnum; id++) { new Thread(new Doww(mubiao, dizhi, id, threadNnum)).start(); } } public static void main(String[] args) { TestIo t = new TestIo("E://aaaa//85、搜狐邮箱.wmv", "E://aaaa//bbbb.wmv", 3); try { t.copy(); } catch (IOException e) { e.printStackTrace(); } } } class Doww extends Thread { String mubiao; String dizhi; int startIndex; int endIndex; int id; int count; int threadNnum; public Doww(String mubiao, String dizhi, int id, int threadNnum) { this.mubiao = mubiao; this.dizhi = dizhi; this.id = id; this.threadNnum = threadNnum; } @Override public void run() { RandomAccessFile fis = null; RandomAccessFile raf = null; try { fis = new RandomAccessFile(new File(mubiao), "r"); raf = new RandomAccessFile(new File(dizhi), "rw"); int total = (int) fis.length(); int count = total / threadNnum; startIndex = id * count; endIndex = (id + 1) * count - 1; fis.seek(startIndex); raf.seek(startIndex); byte[] bytes = new byte[250]; int len = 0; while (startIndex <= endIndex) { len = fis.read(bytes); raf.write(bytes, 0, len); startIndex += len; } } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } }

上次分片下载有bug,bug是下载的线程只是一部分,使用三个线程,结果只有三分之一下载好。

原因是每一个线程,都会产生一个新的io流,每个io流read个write都是从头开始读写,因此读写的文件只能是一部分。相当于每个线程都是从头开始下载文件的。

解决办法,

fis.seek(startIndex);

raf.seek(startIndex);

使用RandomAccessFile的seek,这个方法可以保存文件读写的位置。我控制startIndex每次位置不一样,第一个线程从0开始读写,第二个从count开始读写,第三个  2*count  读写。

这样每次控制读的位置和写的位置我都能控制。尽管每次产生的都是不同的RandomAccessFile对象,但是我控制每次读写位置不一样。

不然如果使用FileInputStream   每次都是不同的对象,每次读都是从头开始读,这样复制下来的是一样的,每个线程读写同样的东西。

 

 

 

 

 

最新回复(0)