黑马程序员技术交流社区

标题: 多线程玩玩IO流,求开导。。。 [打印本页]

作者: lingyuezhixing    时间: 2015-11-25 01:31
标题: 多线程玩玩IO流,求开导。。。
问题在最后面高手可以直接跳,我先从过程说起吧。
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多个字节!!?
我试验是切文本没问题呀
再进行几次测试下,还是对文本就可以,对电影图片就不行。
再检查,检查...检查....
我靠,他妈的哪里有问题,老天耍我的吧!!砸电脑了、/、、



求开导!!



作者: hdhunter    时间: 2015-11-25 10:54
代码格式太乱,看不清楚。待会再看。
作者: lingyuezhixing    时间: 2015-11-25 12:18
hdhunter 发表于 2015-11-25 10:54
代码格式太乱,看不清楚。待会再看。

复制到eclipse上就清楚了,
如果还是不清楚,那就别去浪费时间了
作者: 萧未然    时间: 2015-11-27 23:35
明天看看,感觉毕老师讲的时候没这么复杂的
作者: lingyuezhixing    时间: 2015-11-28 20:41
我兴趣的学友可以转到我的下一个贴,接着本帖进一步讨论
http://bbs.itheima.com/thread-264111-1-1.html
作者: 梦想家Eva    时间: 2015-12-7 00:36
好难啊!!!
作者: 5个半柠檬c    时间: 2015-12-9 00:43
其实你可以直接说下思路 或者你自己敲的哪些代码感觉有点错误的放出来,,,
作者: sunpeijie    时间: 2015-12-19 14:38
文件切割肯定会破坏数据,我切割的视频图片也不能看,但是在把切割的整合了   就完整了
作者: 胆小的狙击手    时间: 2016-1-6 22:50
我提供一个思路:要只想开启五个线程完成这个文件切割的任务,我建议你可以开启一个只有五个线程的线程池,然后分割文件,定义一个字节数组根据要切割的大小来,比如说3M就是3*1024*1024。
定义一个变量记录长度,只要长度不大于文件的大小就说明没有切割完,然后一直不停的让线程池执行任务就行了,我还没有试过这个方法行不行,这是我的思路,我明天试试再给你回复,往采纳
作者: wljr339    时间: 2016-1-13 22:22
本帖最后由 wljr339 于 2016-1-13 22:25 编辑

嗯嗯  其实吧  我学的也不是太好   但是我特别喜欢研究   因为IO流刚学一半    字符流  不能拷贝非文本文档   电影和图片都打不开  或者是看不了  要想复制只能用字节流    希望对你有帮助  




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2