黑马程序员_java多线程玩玩IO流,求开导!!

------- android培训java培训、期待与您交流! ----------


IO流快要块要学完,今天刚好看到文件切割,就想切割大一点的电影来玩玩,嗯嗯。刚好把多线程搬出来玩玩,看我飞起来有多快,

不多说,先来个分析设计:

*
 * 要求:用最快的速度把一部电影按每段50M大小切割并存入C盘下。
 * 
 * 思路:
 * 1,建立5条读取流,每条读取流对应一个线程。
 * 2,在每读取流建立五条打印流。
 * 
 * 做法:
 * 主线程:
 * 1,获取文件大小。
 * 2,以250M大小给文件分段,每段开启一个线程并非对应一个读取流。
 * 3,当达到五个线程时,不再分配文件。
 * 4,当出现一个线程的读取流读完所分配的文件时,在继续给其分配文件。直到把源文件分配完
 * 
 * 读取流线程: (1读取 --2写入 )
 * 0---50---100---150---200---249--
 * 每段读取10M,同时就开启一个A写入流线程。并跳到下一段,读取10M,在开启B写入流。
 * 
 * 如果A写入流完成,判断是否有下一段可读,有读下一段,没有则Await
 * 再跳到下一段读取10M,如果A或Bwait则,唤醒并开始写入,
 * 
 * 写入写入线程:
 * 
 * 
 */

感觉不是很难吗,

开写

-------

-------

...

---

--。。。。

-。。

。。。。。

哇卡,怎么从文件指定的字节流处开始读取,查文档,肯定有,,File类 ...没?!!什么情况,既然还没有子类,炸了吧

既然是读取那找一下读取流,找..找..找..PipedInputStream类,好像有点相关,但还没有真正我想要的。

好吧,看来我是找不到了,


那我就先写我先得到的部分吧,以后再把不足的补上,

继续开工。

一个读取流为一个对象,对应n个打印流线程,

写写写代码就出啦,


输出流:


package com.inout;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;


public class OutputStreamTread implements Runnable {


private File file;
private ArrayList<byte[]> list;
private int beginof;
private int endof;

OutputStreamTread(File file ,ArrayList<byte[]> list , int beginof , int endof){
this.file = file;
this.list= list;
this.beginof =beginof;
this.endof= endof;
}

public void run() {

// while(true){
try {
BufferedOutputStream bufo = 
new BufferedOutputStream(new FileOutputStream(file));
int begin = beginof ;
while(beginof<endof){
bufo.write(list.get(beginof));
beginof++;
bufo.flush();
}
while(begin<endof){
endof--; //释放内存空间,为了避免多线带来的安全问题,采用从最后位,往前擦出。
list.set(endof, null);
}
bufo.close();

}
catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
// }
//如果没有下一个可以输出的了,则 wait

}

// private byte[] nextBytes() {
// return it.next();
// }


}

打印流也来了


package com.inout;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;


public class IntputStreamTread implements Runnable {


private File file;
private int count=1;
IntputStreamTread(File file){
this.file = file ;
}
ArrayList<byte[]> arby = new ArrayList<byte[]>();
public void run() {
// while(true){
try {

BufferedInputStream bufi =
new BufferedInputStream(new FileInputStream(file));
byte[] b = new byte[1024*1024];  //每次读取的长度,
int len = 0 ;
int index = 0 ;
int beginof =0;
int endof = 0 ;
int count = 0;     //循环次数。
int maxcount = 5; //最大循环写入次数后,开启下一个输出流,既:切割的文件大小为 b.length * maxcoutn
int maxsize = 20; //集合最大长度。  最终集合的中大小为 b.length*maxsize
while((len=bufi.read(b))!=-1){
//如果集合未达到最大长度,就往集合中添加。
if(arby.size()<maxsize){
arby.add(new String(b,0,len).getBytes());
count++;
}
//否则,把集合作为循环数组使用。
else{
System.out.println("begiof--"+beginof);
if(index%maxcount==0){
System.out.println("index--"+index);
if(index>=arby.size()) //防止角标越界
index=0;
beginof=index; //寻找,满足条件的起始位置,
while(arby.get(beginof)!=null){
System.out.println(arby.get(beginof));
index=index+maxcount;
if(index>=arby.size()){
index=0;   
}
beginof=index; 
Thread.yield(); //不急,慢慢找,都用其他线程执行完就有了。
}
arby.set(index, new String(b,0,len).getBytes());
index++;
count++;
}
else{
arby.set(index, new String(b,0,len).getBytes());
index=index+1;
count++;
}
}

if(!((count)<maxcount)){
endof=beginof+count;
Thread th = getOutputThread(beginof ,endof);
beginof = endof ;

th.start();
count = 0;
continue;
}
}
if(count>0){
System.out.println(count+"-----");
endof=beginof+count;
Thread th = getOutputThread(beginof ,endof);
th.start();
}


bufi.close();

} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
// }

}
private Thread getOutputThread(int beginof , int endof) {
Thread th = 
new Thread(new OutputStreamTread(new File("G:\\"+count+".part"), arby,beginof ,endof ));
System.out.println(count);
count++;
return th;
}




}

好长,经常角标越界,差点吐血,哭着3也得笑着说还好双十一放血太多吗》


主类就很简单了,


package com.inout;


import java.io.File;


public class TestMain {


public static void main(String[] args) {

File infile = new File("G:\\ab.jpg");
// File infile = new File("G:\\abc.txt");
Thread inth = new Thread(new IntputStreamTread(infile));
inth.start();
}


}


电脑抽风了还是自己抽风了,字体一会儿大,一会儿小,反正我也是醉了


回归正题,

测试方便,写几个文本数据吧?

测试一:

action ———— - - —— 角标越界。

测试二:

action —————— -- 少了两个(字符)字节

......

.....

测试N:

action————————哈哈完美了吧

————————————————————————

来个电影开切:

吓~!这速度,比复制快多了,这什么这么6

属性看一下应为也是没问题的,点--属性

疯了吧,少了50多个字节!!?

我试验是切文本没问题呀

再进行几次测试下,还是对文本就可以,对电影图片就不行。

再检查,检查...检查....

我靠,他妈的哪里有问题,老天耍我的吧!!砸电脑了、/、、

求开导!!




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值