[19/04/03-星期三] IO技术_其它流(RandomAccessFile 随机访问流,SequenceInputStream 合并流)
一、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 合并流)的更多相关文章
- Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)
1.操作基本数据类型的流 1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...
- Java基础知识强化之IO流笔记63:随机访问流RandomAccessFile
1. 随机访问流RandomAccessFile RandomAccessFile类不属于流,是Object类的子类.但它融合了InputStream和OutputStream的功能.支持对随机访问文 ...
- Java IO流-随机访问流
2017-11-05 19:45:51 RandomAccessFile类(随机访问流) RandomAccessFile类:是Object的子类,此类的实例支持对随机访问文件的读取和写入.随机访问文 ...
- 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile
目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...
- [19/04/02-星期二] IO技术_字符流分类总结(含字符转换流InputStreamReader/ OutputStreamWriter,实现字节转字符)
一.概念 ------->1.BufferedReader/BufferedWriter [参考19.03.31文章] *Reader/Writer-------->2.InputStre ...
- [19/03/28-星期四] IO技术_基本概念&字符编码与解码
一.概念 输入(Input) 指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据) 常见的应用: Ø 读取硬盘上的文件内容到程序.例如:播放器打开一个视频文件.word打开一个do ...
- Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)
一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...
- 18 IO流(十五)——RandomAccessFile随机访问文件及使用它进行大文件切割的方法
本文部分内容转自:https://blog.csdn.net/nightcurtis/article/details/51384126 1.RandomAccessFile特点 RandomAcces ...
- [19/04/01-星期一] IO技术_字节流分类总结(含字节数组(Array)流、字节数据(Data)流、字节对象(Object)流)
一.字节流分类概括 -->1.ByteArrayInputStream /ByteArrayOutputStream(数组字节输入输出) InputStream/OutputStr ...
随机推荐
- Firebird 列可空非空修改
2018-12-04 至少到Firebird 3.0.4 已经添加了设置可空 和 非空的语法:如 -- 删除非空(设置为可空) ALTER TABLE TECH ALTER label drop NO ...
- [转]weui-wxss WeUI for 小程序 为微信小程序量身设计
本文转自:https://github.com/weui/weui-wxss/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=tou ...
- MongoDB 线上环境按照及配置(授权方式启动)
1创建文件repo文件 #vim /etc/yum.repos.d/mongodb-org-3.4.repo [mongodb-org-3.4] name=MongoDB Repository bas ...
- 五、mybatis集成使用
1.添加依赖 <!-- mybatis-spring集成--> <dependency> <groupId>org.mybatis.spring.boot</ ...
- 十 DatagramChannel
DatagramChannel是一个能收发UDP包的通道.因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入.它发送和接收的是数据包. 打开 DatagramChannel 下面是 Dat ...
- Light OJ 1422 - Halloween Costumes(区间DP 最少穿几件)
http://www.cnblogs.com/kuangbin/archive/2013/04/29/3051392.html http://www.cnblogs.com/ziyi--caolu/a ...
- vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)
vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于“=”.“d”.“y”,我在无意中发现了它们所具有的相同的一些用法,先举以下三个例子: =nG dnG ynG 其中,n为行号.注意 ...
- Angularjs之依赖注入
一个对象通常有三种方式可以获得对其依赖的控制权: 在内部创建依赖: 通过全局变量进行引用: 在需要的地方通过参数进行传递 依赖注入是通过第三种方式实现的.比如: function SomeClass( ...
- iframe 子页面改变父页面样式
iframe 子窗口调节父窗口样式: $(window.parent.document).find("body").attr("style"," 父元 ...
- CentOS使用fdisk扩展磁盘空间
使用情况: 1. 虚拟机配置150G硬盘,初始化为/dev/sdb1,后因为磁盘空间不够使用,动态扩容至300G,扩容完成后,想要动态扩容/dev/sdb1分区. 2. 磁盘空间300G,之前分区只划 ...