java IO学习笔记------对象流&打印流&文件分割(随机流)&文件的合并(序列流)
对象流-ObjectOutputStream&ObjectInputStream
序列化 反序列化
ObjectOutputStream ObjectInputStream
先写出后读取(先序列化在反序列化)
不仅能操作原始数据(如数据流)还能操作对象
不是所有的对象都能序列化(Serializable)
注意:读写的顺序要一致
对象流练习
package Io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* 对象流
* 1.写出后读取
* 2.读取的顺序与写出保持一致
* 3.不是所有的对象都可以序列化 Serializable
*
* ObjectOutputStream
* ObiectInputStream
* @author 赌徒
*
*/
public class ObjectT8 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//写出 --序列化
ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("data.txt")));//文件流需要关闭
//操作数据类型+数据
oos.writeUTF("张三");
oos.writeInt(18);
oos.writeBoolean(false);
oos.writeChar('a');
//对象
oos.writeObject("李四");
oos.writeObject(new Date());
Employee emp=new Employee("王二",666);
oos.writeObject(emp);
oos.flush();
oos.close();
//读取 -->反序列化
ObjectInputStream ois=new ObjectInputStream(new BufferedInputStream(new FileInputStream("data.txt")));
//顺序与写出一致
String name= ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
System.out.println(name);
System.out.println(age);
System.out.println(flag);
System.out.println(ch);
//对象的数据还原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();
if(str instanceof String) {
String strObj = (String) str;
System.out.println(strObj);
}
if(date instanceof Date) {
Date dateObj = (Date) date;
System.out.println(dateObj);
}
if(employee instanceof Employee) {
Employee empObj = (Employee) employee;
System.out.println(empObj.getName()+"-->"+empObj.getSalary());
}
}
}
//封装数据
class Employee implements java.io.Serializable{
private transient String name; //该数据不需要序列化
private double salary;
public Employee() {
}
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
打印流-PrintStream
构造方法:
PrintStream(OutputStream out,true)可自动刷新
新增方法:
append()
println()
打印流练习
package Io;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**打印流
* PrintStream
* @author 赌徒
*
*/
public class PrintT9 {
public static void main(String[] args) throws FileNotFoundException {
//打印流System.out
PrintStream ps=System.out;
ps.println("打印流");
ps.println(true);
ps=new PrintStream(new BufferedOutputStream(new FileOutputStream("printtest.txt")),true);//内部自带刷新
ps.println("打印流");
ps.println(true);
//重定向输出端
System.setOut(ps);
System.out.println("123");
}
}
文件分割(随机流)-文件的合并(序列流)RandomAccessFile&SequenceInputStream
注意点: 支持读和写 有模式参数 r(读) rw(写)
RandomAccessFile(new File(),模式)
seek(long pos); 随机读取
代码测例:
package Io;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomTest2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//分多少块
File srcFile=new File("src/io/ex1.java");
//总长度
long len=srcFile.length();
//每块大小
int blockSize=1024;
//块数:多少块
int size = (int) Math.ceil(len*1.0/blockSize);
System.out.println(size);
//起始位置和实际大小
int beginpos=0;
int actualSize=(int) (blockSize>len?len:blockSize);
for (int i = 0; i < size; i++) {
beginpos = i*blockSize;
if (i==size-1) {//最后一块
actualSize=(int) len;
}else {
actualSize = blockSize;
len-=actualSize;
}
System.out.println(i+"-->"+beginpos+"-->"+actualSize);
split(size, beginpos, actualSize);
}
raf.close();
}
//指定起始位置,读取下面所有内容
public static void t1() throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//随机读取
raf.seek(2);
//读取
//操作
byte[] flush=new byte[1024];//缓冲数组
int len=-1;//接收长度
while((len=raf.read(flush))!=-1) {
System.out.println(new String(flush,0,len));
}
raf.close();
}
//指定第i块的起始位置和实际长度
public static void split(int i,int beginpos,int actualSize) throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//随机读取
raf.seek(beginpos);
//读取
//操作
byte[] flush=new byte[1024];//缓冲数组
int len=-1;//接收长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {//获取本次读取所有内容
System.out.println(new String(flush,0,len));
actualSize-=len;
}else {
System.out.println(new String(flush,0,actualSize));
break;
}
}
raf.close();
}
//分块思想:指定起始位置和读取长度
public static void t2() throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//起始位置
int beginpos=2;
//读取长度
int actualSize=1026;
//随机读取
raf.seek(beginpos);
//读取
//操作
byte[] flush=new byte[1024];//缓冲数组
int len=-1;//接收长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {//获取本次读取所有内容
System.out.println(new String(flush,0,len));
actualSize-=len;
}else {
System.out.println(new String(flush,0,actualSize));
break;
}
}
raf.close();
}
}
综合练习:
package Io;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomTest2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//分多少块
File srcFile=new File("src/io/ex1.java");
//总长度
long len=srcFile.length();
//每块大小
int blockSize=1024;
//块数:多少块
int size = (int) Math.ceil(len*1.0/blockSize);
System.out.println(size);
//起始位置和实际大小
int beginpos=0;
int actualSize=(int) (blockSize>len?len:blockSize);
for (int i = 0; i < size; i++) {
beginpos = i*blockSize;
if (i==size-1) {//最后一块
actualSize=(int) len;
}else {
actualSize = blockSize;
len-=actualSize;
}
System.out.println(i+"-->"+beginpos+"-->"+actualSize);
split(size, beginpos, actualSize);
}
raf.close();
}
//指定第i块的起始位置和实际长度
public static void split(int i,int beginpos,int actualSize) throws IOException {
RandomAccessFile raf=new RandomAccessFile(new File("src/io/ex1.java"), "r");
//随机读取
raf.seek(beginpos);
//读取
//操作
byte[] flush=new byte[1024];//缓冲数组
int len=-1;//接收长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {//获取本次读取所有内容
raf1.write(flush,0,len);
actualSize-=len;
}else {
raf1.write(flush,0,actualSize);
break;
}
}
raf.close();
}
}
综合练习:
package reIo;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
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 SplitFile {
//源头
private File src;
//目的地(文件夹)
private String destDir;
//所有分割后的文件存储路径
private List<String> destPaths;
//每块大小
private int blockSize;
//块数: 多少块
private int size;
public SplitFile(String srcPath,String destDir) {
this(srcPath,destDir,1024);
}
public SplitFile(String srcPath,String destDir,int blockSize) {
this.src =new File(srcPath);
this.destDir =destDir;
this.blockSize =blockSize;
this.destPaths =new ArrayList<String>();
//初始化
init();
}
//初始化
private void init() {
//总长度
long len = this.src.length();
//块数: 多少块
this.size =(int) Math.ceil(len*1.0/blockSize);
//路径
for(int i=0;i<size;i++) {
this.destPaths.add(this.destDir +"/"+i+"-"+this.src.getName());
}
}
/**
* 分割
* 1、计算每一块的起始位置及大小
* 2、分割
*/
public void split() throws IOException {
//总长度
long len = src.length();
//起始位置和实际大小
int beginPos = 0;
int actualSize = (int)(blockSize>len?len:blockSize);
for(int i=0;i<size;i++) {
beginPos = i*blockSize;
if(i==size-1) { //最后一块
actualSize = (int)len;
}else {
actualSize = blockSize;
len -=actualSize; //剩余量
}
splitDetail(i,beginPos,actualSize);
}
}
/**
* 指定第i块的起始位置 和实际长度
*/
private void splitDetail(int i,int beginPos,int actualSize ) throws IOException {
RandomAccessFile raf =new RandomAccessFile(this.src,"r");
RandomAccessFile raf2 =new RandomAccessFile(this.destPaths.get(i),"rw");
//随机读取
raf.seek(beginPos);
//读取
//3、操作 (分段读取)
byte[] flush = new byte[1024]; //缓冲容器
int len = -1; //接收长度
while((len=raf.read(flush))!=-1) {
if(actualSize>len) { //获取本次读取的所有内容
raf2.write(flush, 0, len);
actualSize -=len;
}else {
raf2.write(flush, 0, actualSize);
break;
}
}
raf2.close();
raf.close();
}
/**
* 文件的合并
*/
public void merge(String destPath) throws IOException {
//输出流
OutputStream os =new BufferedOutputStream( new FileOutputStream(destPath,true));
Vector<InputStream> vi=new Vector<InputStream>();
SequenceInputStream sis =null;
//输入流
for(int i=0;i<destPaths.size();i++) {
vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(i))));
}
sis =new SequenceInputStream(vi.elements());
//拷贝
//3、操作 (分段读取)
byte[] flush = new byte[1024]; //缓冲容器
int len = -1; //接收长度
while((len=sis.read(flush))!=-1) {
os.write(flush,0,len); //分段写出
}
os.flush();
sis.close();
os.close();
}
public static void main(String[] args) throws IOException {
SplitFile sf = new SplitFile("SplitFile.java","dest") ;
sf.split();
sf.merge("abc.java");
}
}
其他章节:
java IO学习笔记------(1)文件字节流
java IO学习笔记------(2)文件字符流&字节数组流
java IO学习笔记------(3)字节缓冲流&字符缓冲流&转换流&数据流