[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 }

浙公网安备 33010602011771号