[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 ...
随机推荐
- Magento 2中文手册教程 - Magento 2 安装流程图
下图提供了安装Magento 2的安装流程概述: 设置你的服务器环境. 安装magento 2 必备软件, PHP, Apache, MySQL. 系统需求详细信息: 2.1.x 系统需求 获得mag ...
- 从 C#编写的Exe里面提取图标和图片
记得原来是可以通过PE直接提取Exe里面的图片的,不知道为什么不能用了,下面是通过加载程序集反射出Resources 里面的图片或者图标: 提取结果直接存放到编译目录了,不知道向左向右,自己又回到Wi ...
- type=file的change事件只能执行一次的解决方案
最近帮朋友做个项目中遇到了type=file change事件只能执行一次的问题,度娘了一下,发现提供了各种解决方案,所以决定记录一下我的思考方向和最终解决方式. 起初帮朋友做个项目,项目中遇到上传文 ...
- 5、springboot之修改端口号
在resources中加入application.properties文件,里面加入 servier.port = 端口号 访问的时候,就用localhost:端口号 完事
- 读EntityFramework.DynamicFilters源码_心得_单元测试03
上个星期我们只是显示了一个示例,怎么在EF的框架内,注入我们拓展的动态过滤器 第一步:安装EntityFramework.DynamicFilters 第二步:重写OnModelCreating方法 ...
- Idea15 常用设置(一):JDK、SVN
1:显示行号 File->Settings->General->Appearance 2: 代码自动补齐即使是小写字母也会弹出代码补齐提示 3:自动编译 设置 4: 设 ...
- 关于tr:hover变色的问题
最近在给table里面的tr标签添加高亮背景色显示的时候,遇到一个坑,HTML结构如下: <tr> <td></td> <td></td> ...
- eclipse插件开发常见的问题及解决办法
莫名其妙地我的某个Plug-in Projects出现了这样的Error:An API baseline has not been set for the current workspace.虽然后来 ...
- Oracle中的索引详解(转载)
一. ROWID的概念 存储了row在数据文件中的具体位置:64位 编码的数据,A-Z, a-z, 0-9, +, 和 /, row在数据块中的存储方式 SELECT ROWID, last_name ...
- ActiveMQ相关:
MQ连接字符串:failover:tcp://127.0.0.1:61616 管理地址:http://localhost:8161/admin/