[19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)

一、RandomAccessFile 随机访问流

【版本1】

 1 /*
 2 *RandomAccessFile  所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件
 3  * 实现文件的拆分与合并  模拟下载的原理
 4  */
 5 package cn.sxt.test;
 6 
 7 import java.io.File;
 8 import java.io.IOException;
 9 import java.io.RandomAccessFile;
10 
11 
12 public class Test_0403_RandomAccessFile {
13     public static void main(String[] args) throws IOException {
14         File file=new File("src.txt");
15         RandomAccessFile raf =new RandomAccessFile(file, "r");//"r"代表要读取这个文件 "rw"代表读取和写入 
16         //raf.seek(10);//从第10个字节开始读取文件,然后输出余下的所有字节
17         long len=raf.length();//文件的大小
18         int blockSize=1024;//分块,每块的大小
19         int block=(int)Math.ceil(len*1.0/blockSize);//向上取整
20         System.out.println("共"+raf.length()+"字节");
21         System.out.println("划分"+block+"块");
22         
23         int beginFlag=0;//起始位置为0 
24         int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
25         for (int i = 0; i < block; i++) {
26             beginFlag=i*blockSize;
27             if (i==block-1) {//最后一块的情形
28                 actSize=(int)len;
29                 
30             } else {//其它的整块
31                 actSize=blockSize;// blockSize=1024 定值
32                 len=len-actSize;//len-=actSize 实际的剩余量
33             }
34             System.out.println("第"+(i+1)+"块  "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
35             spilt(i,beginFlag,actSize);
36         }
37         
38         
39         raf.close();
40         
41         
42     }
43     public static void spilt(int i,int beginFlag,int actSize) throws IOException {
44         File file=new File("src.txt");
45         RandomAccessFile raf =new RandomAccessFile(file, "r");
46         raf.seek(beginFlag);
47         byte buffer[]=new byte[1024];
48         int len=0;
49         while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取    
50             if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
51                 System.out.println(new String(buffer,0,len));
52                 actSize=actSize-len; //减去本次获取的内容
53             } else {//那么再读取一次
54                 System.out.println(new String(buffer,0,len));
55                 break;
56             }
57             
58         }
59         
60         raf.close();
61     
62     }
63     
64     //第2个版本
65             //raf.seek(10);//从第10个字节开始读取文件,然后输出余下的所有字节
66             /*int beginFlag=10;//起始位置
67             int Actlength=1026;//想要读取输出的实际大小
68             int blockSize=1024;//分块,每块的大小
69             int block=(int)Math.ceil(raf.length()/blockSize);//向上取整
70             raf.seek(beginFlag);
71             
72             
73             
74             byte buffer[]=new byte[1024];
75             int len=0;
76             while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取    
77                 if (Actlength>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
78                     System.out.println(new String(buffer,0,len));
79                     Actlength=Actlength-len; //减去本次获取的内容
80                 } else {//那么再读取一次
81                     System.out.println(new String(buffer,0,len));
82                     break;
83                 }
84                 
85             }
86             
87             raf.close();*/
88 
89 }

【版本2】

 1 /*
 2  *RandomAccessFile 分割文件改良 封装一下  --最终版 
 3  */
 4 package cn.sxt.test;
 5 
 6 import java.io.File;
 7 import java.io.IOException;
 8 import java.io.RandomAccessFile;
 9 import java.util.ArrayList;
10 import java.util.List;
11 
12 public class Test_0403_RandomAccessFile2 {
13     public static void main(String[] args) throws IOException {
14         SplitFile spFile=new SplitFile("src.txt", "dest", 1024);//也可以传进去图片
15         spFile.split();
16     
17     }
18 }
19 
20 class SplitFile{
21     private File srcFile;//源文件
22     private String destDir;//目的文件夹
23     private List<String> destPaths;//分割后的文件的存储路径
24     private int blockSize;//每块的大小
25     private int block;//多少块 
26                       //srcPath 源文件的路径  String 目标文件,  blockSize 每块的大小
27     public SplitFile(String srcPath, String destDir, int blockSize) { //构造方法  初始化用的
28         super();
29         this.srcFile = new File(srcPath);//源文件
30         this.destDir = destDir;//目录文件
31         this.blockSize = blockSize;
32         this.destPaths=new ArrayList<String>();
33         init();
34 
35     }
36     //初始化一些具体东西
37     private void init(){
38 
39         long len=this.srcFile.length();//文件的大小
40         this.block=(int)Math.ceil(len*1.0/blockSize);//向上取整
41         System.out.println("源文件共"+srcFile.length()+"字节");
42         System.out.println("划分"+block+"块");
43 
44         for (int i = 0; i < block; i++) {
45             this.destPaths.add(this.destDir+"/"+i+"_"+this.srcFile.getName());
46         }
47     }
48 
49     //具体的分割过程 1、计算每一块的起始位置及大小 2、分割
50     public void  split() throws IOException{
51         long len=srcFile.length();
52 
53         int beginFlag=0;//起始位置为0 
54         int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
55         for (int i = 0; i < block; i++) {
56             beginFlag=i*blockSize;
57             if (i==block-1) {//最后一块的情形
58                 actSize=(int)len;
59 
60             } else {//其它的整块
61                 actSize=blockSize;// blockSize=1024 定值
62                 len=len-actSize;//len-=actSize 实际的剩余量
63             }
64             System.out.println("第"+(i+1)+"块  "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
65             spiltDetail(i, beginFlag, actSize);
66         }
67     }
68 
69     private  void spiltDetail(int i,int beginFlag,int actSize) throws IOException {
70     
71         RandomAccessFile raf =new RandomAccessFile(this.srcFile, "r");//只读模式 this.srcFile代表文件对象
72         RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i), "rw");//读写模式 ,写出的路径
73         
74         raf.seek(beginFlag);
75         byte buffer[]=new byte[1024];
76         int len=0;
77         while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取    
78             if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
79                 //System.out.println(new String(buffer,0,len));
80                 raf2.write(buffer, 0, len);
81                 actSize=actSize-len; //减去本次获取的内容
82             } else {//那么再读取一次
83                 //System.out.println(new String(buffer,0,actSize));
84                 raf2.write(buffer, 0, actSize);
85 
86                 break;
87             }
88 
89         }
90 
91         raf.close();
92         raf2.close();
93 
94     }
95 
96 
97 }

 二、SequenceInputStream 合并流

  1 /*
  2  *RandomAccessFile 分割文件改良 封装一下  --最终版 
  3  *SequenceInputStream 合并流,加入
  4  */
  5 package cn.sxt.test;
  6 
  7 import java.io.File;
  8 import java.io.FileInputStream;
  9 import java.io.FileNotFoundException;
 10 import java.io.FileOutputStream;
 11 import java.io.IOException;
 12 import java.io.InputStream;
 13 import java.io.OutputStream;
 14 import java.io.RandomAccessFile;
 15 import java.io.SequenceInputStream;
 16 import java.util.ArrayList;
 17 import java.util.List;
 18 import java.util.Vector;
 19 
 20 public class Test_0403_RandomAccessFile2 {
 21     public static void main(String[] args) throws IOException {
 22         SplitFile spFile=new SplitFile("src.txt", "dest", 1024);//也可以传进去图片
 23         spFile.split();//文件分割
 24         //spFile.merge("dest/src_2.txt");//文件的合并
 25         spFile.merge2("dest/src_3.txt");//文件的合并,验证SequenceInputStream流 效果是一样的    
 26     }
 27 }
 28 
 29 class SplitFile{
 30     private File srcFile;//源文件
 31     private String destDir;//目的文件夹
 32     private List<String> destPaths;//分割后的文件的存储路径
 33     private int blockSize;//每块的大小
 34     private int block;//多少块 
 35                       //srcPath 源文件的路径  String 目标文件,  blockSize 每块的大小
 36     public SplitFile(String srcPath, String destDir, int blockSize) { //构造方法  初始化用的
 37         super();
 38         this.srcFile = new File(srcPath);//源文件
 39         this.destDir = destDir;//目录文件
 40         this.blockSize = blockSize;
 41         this.destPaths=new ArrayList<String>();
 42         init();
 43 
 44     }
 45     //初始化一些具体东西
 46     private void init(){
 47 
 48         long len=this.srcFile.length();//文件的大小
 49         this.block=(int)Math.ceil(len*1.0/blockSize);//向上取整
 50         System.out.println("源文件共"+srcFile.length()+"字节");
 51         System.out.println("划分"+block+"块");
 52 
 53         for (int i = 0; i < block; i++) {
 54             this.destPaths.add(this.destDir+"/"+i+"_"+this.srcFile.getName());
 55         }
 56     }
 57 
 58     //具体的分割过程 1、计算每一块的起始位置及大小 2、分割
 59     public void  split() throws IOException{
 60         long len=srcFile.length();
 61 
 62         int beginFlag=0;//起始位置为0 
 63         int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
 64         for (int i = 0; i < block; i++) {
 65             beginFlag=i*blockSize;
 66             if (i==block-1) {//最后一块的情形
 67                 actSize=(int)len;
 68 
 69             } else {//其它的整块
 70                 actSize=blockSize;// blockSize=1024 定值
 71                 len=len-actSize;//len-=actSize 实际的剩余量
 72             }
 73             System.out.println("第"+(i+1)+"块  "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
 74             spiltDetail(i, beginFlag, actSize);
 75         }
 76     }
 77 
 78     private  void spiltDetail(int i,int beginFlag,int actSize) throws IOException {
 79     
 80         RandomAccessFile raf =new RandomAccessFile(this.srcFile, "r");//只读模式 this.srcFile代表文件对象
 81         RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i), "rw");//读写模式 ,写出的路径
 82         
 83         raf.seek(beginFlag);
 84         byte buffer[]=new byte[1024];
 85         int len=0;
 86         while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取    
 87             if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
 88                 //System.out.println(new String(buffer,0,len));
 89                 raf2.write(buffer, 0, len);
 90                 actSize=actSize-len; //减去本次获取的内容
 91             } else {//那么再读取一次
 92                 //System.out.println(new String(buffer,0,actSize));
 93                 raf2.write(buffer, 0, actSize);
 94 
 95                 break;
 96             }
 97 
 98         }
 99 
100         raf.close();
101         raf2.close();
102 
103     }
104     //文件的合并 merge:使融入,混合
105     public void  merge(String destPath) throws IOException {
106         //输出流
107         OutputStream oStream=new FileOutputStream(destPath,true);//true表示在文件后追加
108         //输入流, 有多个分割后的文件组成,他们在容器中存放着
109         for (int i = 0; i < destPaths.size(); i++) {
110             InputStream iStream=new FileInputStream(destPaths.get(i));
111             //内容写入目标文件
112             byte[] butter=new byte[1024];
113             int len=0;
114             while ((len=iStream.read(butter))!=-1) {
115                 oStream.write(butter,0,len);    
116             }
117             oStream.flush();
118             iStream.close();        
119             
120         }    
121         oStream.close();
122     }
123     //SequenceInputstream 合并流. Sequence:使按顺序排列,合并的 vector向量的、矢量的
124     public void  merge2(String destPath) throws IOException {
125         //输出流
126         OutputStream oStream=new FileOutputStream(destPath,true);//true表示在文件后追加
127         Vector<InputStream> vi =new Vector<InputStream>();
128         
129         //输入流, 有多个分割后的文件组成,他们在容器中存放着,用destPaths.get(i)表示着
130         for (int i = 0; i < destPaths.size(); i++) {            
131             vi.add( new FileInputStream(destPaths.get(i)) );//输入流放到容器里边                
132         }
133         
134         SequenceInputStream sis =new SequenceInputStream( vi.elements() );//把vi对象中的元素进行序列化,排列合并
135         byte[] butter=new byte[1024];
136         int len=0;
137         while ((len=sis.read(butter))!=-1) {
138             oStream.write(butter,0,len);    
139         }
140         oStream.flush();
141         oStream.close();
142         sis.close();
143     }
144     
145     
146 
147 }

 

posted @ 2019-04-05 00:35  ID长安忆  阅读(201)  评论(0)    收藏  举报