一、RandomAccessFile 随机访问流

【版本1】

 /*
*RandomAccessFile 所谓随机读取就是 指定位置开始或指定位置结束 的读取写入文件
* 实现文件的拆分与合并 模拟下载的原理
*/
package cn.sxt.test; import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile; public class Test_0403_RandomAccessFile {
public static void main(String[] args) throws IOException {
File file=new File("src.txt");
RandomAccessFile raf =new RandomAccessFile(file, "r");//"r"代表要读取这个文件 "rw"代表读取和写入
//raf.seek(10);//从第10个字节开始读取文件,然后输出余下的所有字节
long len=raf.length();//文件的大小
int blockSize=1024;//分块,每块的大小
int block=(int)Math.ceil(len*1.0/blockSize);//向上取整
System.out.println("共"+raf.length()+"字节");
System.out.println("划分"+block+"块"); int beginFlag=0;//起始位置为0
int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
for (int i = 0; i < block; i++) {
beginFlag=i*blockSize;
if (i==block-1) {//最后一块的情形
actSize=(int)len; } else {//其它的整块
actSize=blockSize;// blockSize=1024 定值
len=len-actSize;//len-=actSize 实际的剩余量
}
System.out.println("第"+(i+1)+"块 "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
spilt(i,beginFlag,actSize);
} raf.close(); }
public static void spilt(int i,int beginFlag,int actSize) throws IOException {
File file=new File("src.txt");
RandomAccessFile raf =new RandomAccessFile(file, "r");
raf.seek(beginFlag);
byte buffer[]=new byte[1024];
int len=0;
while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取
if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
System.out.println(new String(buffer,0,len));
actSize=actSize-len; //减去本次获取的内容
} else {//那么再读取一次
System.out.println(new String(buffer,0,len));
break;
} } raf.close(); } //第2个版本
//raf.seek(10);//从第10个字节开始读取文件,然后输出余下的所有字节
/*int beginFlag=10;//起始位置
int Actlength=1026;//想要读取输出的实际大小
int blockSize=1024;//分块,每块的大小
int block=(int)Math.ceil(raf.length()/blockSize);//向上取整
raf.seek(beginFlag); byte buffer[]=new byte[1024];
int len=0;
while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取
if (Actlength>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
System.out.println(new String(buffer,0,len));
Actlength=Actlength-len; //减去本次获取的内容
} else {//那么再读取一次
System.out.println(new String(buffer,0,len));
break;
} } raf.close();*/ }

【版本2】

 /*
*RandomAccessFile 分割文件改良 封装一下 --最终版
*/
package cn.sxt.test; import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List; public class Test_0403_RandomAccessFile2 {
public static void main(String[] args) throws IOException {
SplitFile spFile=new SplitFile("src.txt", "dest", 1024);//也可以传进去图片
spFile.split(); }
} class SplitFile{
private File srcFile;//源文件
private String destDir;//目的文件夹
private List<String> destPaths;//分割后的文件的存储路径
private int blockSize;//每块的大小
private int block;//多少块
//srcPath 源文件的路径 String 目标文件, blockSize 每块的大小
public SplitFile(String srcPath, String destDir, int blockSize) { //构造方法 初始化用的
super();
this.srcFile = new File(srcPath);//源文件
this.destDir = destDir;//目录文件
this.blockSize = blockSize;
this.destPaths=new ArrayList<String>();
init(); }
//初始化一些具体东西
private void init(){ long len=this.srcFile.length();//文件的大小
this.block=(int)Math.ceil(len*1.0/blockSize);//向上取整
System.out.println("源文件共"+srcFile.length()+"字节");
System.out.println("划分"+block+"块"); for (int i = 0; i < block; i++) {
this.destPaths.add(this.destDir+"/"+i+"_"+this.srcFile.getName());
}
} //具体的分割过程 1、计算每一块的起始位置及大小 2、分割
public void split() throws IOException{
long len=srcFile.length(); int beginFlag=0;//起始位置为0
int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
for (int i = 0; i < block; i++) {
beginFlag=i*blockSize;
if (i==block-1) {//最后一块的情形
actSize=(int)len; } else {//其它的整块
actSize=blockSize;// blockSize=1024 定值
len=len-actSize;//len-=actSize 实际的剩余量
}
System.out.println("第"+(i+1)+"块 "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
spiltDetail(i, beginFlag, actSize);
}
} private void spiltDetail(int i,int beginFlag,int actSize) throws IOException { RandomAccessFile raf =new RandomAccessFile(this.srcFile, "r");//只读模式 this.srcFile代表文件对象
RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i), "rw");//读写模式 ,写出的路径 raf.seek(beginFlag);
byte buffer[]=new byte[1024];
int len=0;
while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取
if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
//System.out.println(new String(buffer,0,len));
raf2.write(buffer, 0, len);
actSize=actSize-len; //减去本次获取的内容
} else {//那么再读取一次
//System.out.println(new String(buffer,0,actSize));
raf2.write(buffer, 0, actSize); break;
} } raf.close();
raf2.close(); } }

二、SequenceInputStream 合并流

 /*
*RandomAccessFile 分割文件改良 封装一下 --最终版
*SequenceInputStream 合并流,加入
*/
package cn.sxt.test; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector; public class Test_0403_RandomAccessFile2 {
public static void main(String[] args) throws IOException {
SplitFile spFile=new SplitFile("src.txt", "dest", 1024);//也可以传进去图片
spFile.split();//文件分割
//spFile.merge("dest/src_2.txt");//文件的合并
spFile.merge2("dest/src_3.txt");//文件的合并,验证SequenceInputStream流 效果是一样的
}
} class SplitFile{
private File srcFile;//源文件
private String destDir;//目的文件夹
private List<String> destPaths;//分割后的文件的存储路径
private int blockSize;//每块的大小
private int block;//多少块
//srcPath 源文件的路径 String 目标文件, blockSize 每块的大小
public SplitFile(String srcPath, String destDir, int blockSize) { //构造方法 初始化用的
super();
this.srcFile = new File(srcPath);//源文件
this.destDir = destDir;//目录文件
this.blockSize = blockSize;
this.destPaths=new ArrayList<String>();
init(); }
//初始化一些具体东西
private void init(){ long len=this.srcFile.length();//文件的大小
this.block=(int)Math.ceil(len*1.0/blockSize);//向上取整
System.out.println("源文件共"+srcFile.length()+"字节");
System.out.println("划分"+block+"块"); for (int i = 0; i < block; i++) {
this.destPaths.add(this.destDir+"/"+i+"_"+this.srcFile.getName());
}
} //具体的分割过程 1、计算每一块的起始位置及大小 2、分割
public void split() throws IOException{
long len=srcFile.length(); int beginFlag=0;//起始位置为0
int actSize=(int)(blockSize>len?len:blockSize);//实际大小,如果实际大小不到1024则取实际大小
for (int i = 0; i < block; i++) {
beginFlag=i*blockSize;
if (i==block-1) {//最后一块的情形
actSize=(int)len; } else {//其它的整块
actSize=blockSize;// blockSize=1024 定值
len=len-actSize;//len-=actSize 实际的剩余量
}
System.out.println("第"+(i+1)+"块 "+"起始下标:"+beginFlag+" 实际长度:"+actSize);
spiltDetail(i, beginFlag, actSize);
}
} private void spiltDetail(int i,int beginFlag,int actSize) throws IOException { RandomAccessFile raf =new RandomAccessFile(this.srcFile, "r");//只读模式 this.srcFile代表文件对象
RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i), "rw");//读写模式 ,写出的路径 raf.seek(beginFlag);
byte buffer[]=new byte[1024];
int len=0;
while ((len=raf.read(buffer))!=-1) { //加了个缓存数组buffer逐个读取
if (actSize>len) {//如果想要的大小大于缓存的大小 ,先获取读取的全部内容
//System.out.println(new String(buffer,0,len));
raf2.write(buffer, 0, len);
actSize=actSize-len; //减去本次获取的内容
} else {//那么再读取一次
//System.out.println(new String(buffer,0,actSize));
raf2.write(buffer, 0, actSize); break;
} } raf.close();
raf2.close(); }
//文件的合并 merge:使融入,混合
public void merge(String destPath) throws IOException {
//输出流
OutputStream oStream=new FileOutputStream(destPath,true);//true表示在文件后追加
//输入流, 有多个分割后的文件组成,他们在容器中存放着
for (int i = 0; i < destPaths.size(); i++) {
InputStream iStream=new FileInputStream(destPaths.get(i));
//内容写入目标文件
byte[] butter=new byte[1024];
int len=0;
while ((len=iStream.read(butter))!=-1) {
oStream.write(butter,0,len);
}
oStream.flush();
iStream.close(); }
oStream.close();
}
//SequenceInputstream 合并流. Sequence:使按顺序排列,合并的 vector向量的、矢量的
public void merge2(String destPath) throws IOException {
//输出流
OutputStream oStream=new FileOutputStream(destPath,true);//true表示在文件后追加
Vector<InputStream> vi =new Vector<InputStream>(); //输入流, 有多个分割后的文件组成,他们在容器中存放着,用destPaths.get(i)表示着
for (int i = 0; i < destPaths.size(); i++) {
vi.add( new FileInputStream(destPaths.get(i)) );//输入流放到容器里边
} SequenceInputStream sis =new SequenceInputStream( vi.elements() );//把vi对象中的元素进行序列化,排列合并
byte[] butter=new byte[1024];
int len=0;
while ((len=sis.read(butter))!=-1) {
oStream.write(butter,0,len);
}
oStream.flush();
oStream.close();
sis.close();
} }

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

  1. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  2. Java基础知识强化之IO流笔记63:随机访问流RandomAccessFile

    1. 随机访问流RandomAccessFile RandomAccessFile类不属于流,是Object类的子类.但它融合了InputStream和OutputStream的功能.支持对随机访问文 ...

  3. Java IO流-随机访问流

    2017-11-05 19:45:51 RandomAccessFile类(随机访问流) RandomAccessFile类:是Object的子类,此类的实例支持对随机访问文件的读取和写入.随机访问文 ...

  4. 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile

    目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...

  5. [19/04/02-星期二] IO技术_字符流分类总结(含字符转换流InputStreamReader/ OutputStreamWriter,实现字节转字符)

    一.概念 ------->1.BufferedReader/BufferedWriter [参考19.03.31文章] *Reader/Writer-------->2.InputStre ...

  6. [19/03/28-星期四] IO技术_基本概念&字符编码与解码

    一.概念 输入(Input)  指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据) 常见的应用: Ø 读取硬盘上的文件内容到程序.例如:播放器打开一个视频文件.word打开一个do ...

  7. Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)

    一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...

  8. 18 IO流(十五)——RandomAccessFile随机访问文件及使用它进行大文件切割的方法

    本文部分内容转自:https://blog.csdn.net/nightcurtis/article/details/51384126 1.RandomAccessFile特点 RandomAcces ...

  9. [19/04/01-星期一] IO技术_字节流分类总结(含字节数组(Array)流、字节数据(Data)流、字节对象(Object)流)

    一.字节流分类概括 -->1.ByteArrayInputStream /ByteArrayOutputStream(数组字节输入输出)        InputStream/OutputStr ...

随机推荐

  1. 《MySQL 基础课程》笔记整理(进阶篇)(未完)

    一.MySQL服务安装及命令使用 安装过程就不写了,毕竟百度经验一大把 MySQL 官方文档 MySQL 参考手册中文版 1.MySQL简介 ​ RDBMS(Relational Database M ...

  2. No.2一步步学习vuejs 实例demo篇

    简单应用Vue.js 的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统: <div id="app"> {{ message }} </d ...

  3. JavaWeb之JSP原理

    1.为什么需要JSP? 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变.如果使用Servlet程序来输出只有局部内容需要改动的网页,其中所有的静态内容也需要程序员用jav ...

  4. 基于easyUI实现系统日志管理

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. log.jsp:系统日志管理界面 <!DOCTYPE html PUBLIC "-//W ...

  5. Android源码下编译APK步骤

    1.进入android源码目录下的build下执行:source envsetup.sh 后继续在该路径下执行lunch. 2.编写完成工程 3.编写Android.mk文件,放入工程目录下     ...

  6. ugui之圆角矩形头像实现

    这个是参考大神的修改了一下渲染方式实现的,可以去查看原帖的,原贴是圆形头像,原理讲的非常详细 点击这里 我写的这个只支持正方形图片,效果是酱紫的~ 一共三个代码,还需要两个代码,原帖里都有的,我只是修 ...

  7. CSS 盒子模型及 float 和 position

    ## CSS和模型 ##CSS盒模型本质上是一个盒子,封装周围的 HTML 元素,包括 外边距(marign),边框(border),填充(padding),内容物(content) 盒子模型的类型: ...

  8. 【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较

    样本:1MB的JSON文件,引入后生成500份的一个数组: 结果如下: 拷贝性能: JSON.parse(JSON.stringify()) 的方法:2523.55517578125ms immuta ...

  9. 前端学习之路之CSS (二)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ id选择器id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式,CSS 中 id 选择器以 &quo ...

  10. Apache Maven 3.5.0配置安装

    1.maven 3.5 下载地址:http://maven.apache.org/download.cgi 2.下载了解压到 3.配置环境变量 4.测试看是否安装成功 5.maven配置(全局配置,用 ...