javaseday24(文件切割器 合并 序列化 随机访问文件特殊的流 管道流)

来源:互联网 发布:ios映射软件 编辑:程序博客网 时间:2024/06/05 09:31
*
 * 文件切割按照 文件大小 或者 文件个数
 * 按照文件大小  不管怎么样都按照2M切
 * 因为每个文件大小不固定   按照个数 可能每个很大
 * 每个流关联一个文件 几个文件几个流
 */
public class SpiltDemo01 {
private static final int SIZE = 1048576;


public static void main(String[] args) throws IOException {
// spiltFile();
File file = new File("d:\\1.png");
spiltFile(file);//需要传入一个文件 不能直接写路径名 无法识别


}


public static void spiltFile(File file) throws IOException {
//用读取流关联源文件
FileInputStream fis = new FileInputStream(file);
//定义一个1m的缓冲区
byte[] buf = new byte[SIZE];
//创建目的地
FileOutputStream fos = null;


int len = 0;
int count = 1;
/*
* 切割文件时 必须记录住被切割文件的名称 以及切割出来碎片文件的个数以方便于合并
* 这个信息为了描述 使用键值对的方式 用到了properties对象
*/
Properties prop = new Properties();




File dir =new File("c:\\partfiles");
if(!dir.exists())
dir.mkdirs();
while((len=fis.read(buf))!=-1){
fos = new FileOutputStream(new File(dir,(count++)+".part"));//后缀名随便写 因为自己解析 不用系统解析
fos.write(buf, 0, len);
fos.close();
}
//将被切割的文件的信息保存到prop集合中
prop.setProperty("partcount", count+"");
prop.setProperty("filename", file.getName());




fos = new FileOutputStream(new File(dir, count+".properties"));
//将prop集合中的数据存储到文件中
prop.store(fos, "save file info");
fis.close();
}
}


//合并文件

public class MergeFileDemo01 {
public static void main(String[] args) throws IOException {
File dir = new File("c:\\partfiles");
// mergeFile(dir);
mergeFile_2(dir);
}


public static void mergeFile_2(File dir) throws IOException {
/*
* 获取指定目录下的配置文件
*/
File[] files = dir.listFiles(new suffixFilter(".properties"));
if(files.length!=1)
throw new RuntimeException(dir+",该目录下没有properties 的扩展名文件或者不唯一");
//记录配置文件文件对象
File confile = files[0];
//获取该文件中的信息——————————————————————————————
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(confile);
prop.load(fis);
String filename = prop.getProperty("filename");
int count = Integer.parseInt(prop.getProperty("partcount"));//因为返回的是字符串 所以要转化成int
//获取该目录下的所有碎片文件————————————————————————
File[] partFiles = dir.listFiles(new suffixFilter(".part"));
if(partFiles.length!=(count-1)){
throw new RuntimeException("碎片文件不符合要求 个数不对 应该"+count+"个");
}
//将碎片文件和流对象关联并存储到集合中
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int i = 0; i < partFiles.length; i++) {
al.add(new FileInputStream(partFiles[i]));
}
//将多个流合并成一个序列流
Enumeration<FileInputStream> en = Collections.enumeration(al);


SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir, filename));
byte[] buf = new byte[1024];
int len =0;
while((len=sis.read(buf))!=-1){
fos.write(buf, 0, len);
}
fos.close();
sis.close();
}


public static void mergeFile(File dir) throws IOException{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int i = 1; i <=1; i++) {
al.add(new FileInputStream(new File(dir,i+".part")));
}

Enumeration<FileInputStream> en = Collections.enumeration(al);

SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir, "1.bmp"));
byte[] buf = new byte[1024];
int len =0;
while((len=sis.read(buf))!=-1){
fos.write(buf, 0, len);
}
fos.close();
sis.close();


}

}

//后缀名过滤器

public class suffixFilter implements FilenameFilter {

private String suffix;

public suffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}


/*
 * 输入和输出相对应
 * 操作对象 ObjectInputStream ObjectOutputStram
 * 对象在堆中
 * 把对象从堆内存 存到了硬盘上
 */
public class ObjectStreamDemo01 {
public static void main(String[] args) throws IOException, IOException, ClassNotFoundException {
// writeObject();
readObject();
}


private static void readObject() throws ClassNotFoundException, IOException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
//对象反序列化
Person p = (Person) ois.readObject();//内存中没有Person.class文件无法读出这个对象
System.out.println(p.getName()+"..."+p.getAge());
ois.close();
}


private static void writeObject() throws FileNotFoundException, IOException {


ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));//特定的对象存储形式  可读性高
//对象序列话 将对象排队存到硬盘上
//被序列化的对象必须实现 serializable接口
oos.writeObject(new Person("小强",11));
oos.close();
}
}

/*
 * serializable 用于给被序列化的类加入ID号
 * 用于判断类和对象是否是同一个版本 版本号不同会发生无效类异常 InvalidClassExcepton
 * 可以在服务器 崩溃 恢复后 恢复你的对象  存储你的对象
 */
public class Person implements Serializable/*标记接口  表明是合格产品 想用 就实现 */{


private static final long serialVersionUID = 165645444L;
/*
* transient 非静态数据 不想被序列化 可以使用这个关键字修饰
* 不是公共 但是是特有的
*/
private transient String name;//短暂 对象值会在堆 但不会写到硬盘上
private int age=11;//静态后 无法迁入



/*
* RandomAccessFile
* 看到类的名字 查API 不是IO体系中的子类
*
* 特点
* 1、该对象既能读 又能写
* 2、该对象内部维护了一个byte 数组 并通过指针可以操作数组中的元素
* 3、可以通过 getFilePointer方法 获取指针的位置 和通过seek方法设置指针的位置
* 4、其实该对象就是将字节输入流和输出流进行了封装
* 5、该对象的源或者目的只能是文件 通过构造函数就可以看出

* 断点续传中 用到 了 randomAccessFil 技术 多个点传送数据 也是多线程会用到的
*/
// writeFile();
// readFile();
randomFile();
}
private static void randomFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
//往指定位置写入数据 默认从0角标 替换数据
// raf.seek(3*8);
raf.write("李四".getBytes());//需要使用 字节数组 所以用 字符的getBytes 转换成字节数组
raf.write(44);
raf.close();
}
private static void readFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");
//通过seek 设置指针的位置
raf.seek(1*8);//随机的读取  只要指定指针的位置即可  从下个开读?
byte[] buf = new byte[4];
raf.read(buf);
int age = raf.readInt();//工具方法 不用自己弄个数组 方便
String name = new String(buf);
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
//使用RandomAccessFile 对象写入一些人员信息 比如姓名和年龄
//close 说明一定有流
public static void writeFile() throws IOException{
/*
* 如果文件不存在 则创建 如果文件存在 不创建
*
*/
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
raf.write("张三".getBytes());
// raf.write(607);//只写最低的字节
raf.writeInt(17);//使用 int 可以保留前3个字节
raf.write("张三".getBytes());
// raf.write(607);//只写最低的字节
raf.writeInt(18);//使用 int 可以保留前3个字节
raf.close();
}


public class PipedInputStreamDemo_01 {
public static void main(String[] args) throws IOException {
PipedInputStream input = new PipedInputStream();//要么初始化一个输出 要么connect
PipedOutputStream output = new PipedOutputStream();
input.connect(output);
new Thread(new Input(input)).start();
new Thread(new Output(output)).start();
//指定读取数据的时候 使用
//没有发就等待


}
}
class Input implements Runnable{
private PipedInputStream in;
Input(PipedInputStream in) {
this.in = in;
}
@Override
public void run(){
try {
byte[] buf = new byte[1024];
int len =in.read(buf);
String s = new String(buf, 0, len);
System.out.println(s);
in.close();
} catch (IOException e) {


e.printStackTrace();
}


}


}
class Output implements Runnable{
PipedOutputStream out = new PipedOutputStream();
public Output(PipedOutputStream out) {
this.out = out;
}
@Override
public void run() {
try {
Thread.sleep(5000);
out.write("hi,管道".getBytes());
out.close();
} catch (IOException | InterruptedException e) {


e.printStackTrace();
}
}
}





阅读全文
0 0
原创粉丝点击