1.IO流的设计模式就是装饰设计模式:
主要表现在处理流,就是起一个增强的作用;
2.类与类之间的关系
3.文件夹的copy
注意文件夹的拷贝,不能将父目录拷贝到子目录里,这样会进入一个死循环,我们可以通过判断父目录的文件地址是否包含子目录来判断,如果包含就说行;
4.文件的分割与合并
ceil
public static double ceil(double a)
返回大于或等于参数的最小(最接近负无穷大)
double值,并等于数学整数。 特殊情况:
如果参数值已经等于数学整数,则结果与参数相同。 如果参数为NaN或无穷大或正零或负零,则结果与参数相同。 如果参数值小于零但大于-1.0,则结果为负零。 需要注意的是价值
Math.ceil(x)正是价值
-Math.floor(-x) 。
参数
a - 一个值。
结果
最大(最接近负无穷大)的浮点值大于或等于参数,并且等于一个数学整数。
package filesplit;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
/**
*
* 文件的分割
*
* @author Wang
*
*/
public class splitFile {
private String fileName;
private String filePath;
private long length;// 这个是目标文件的大小
private int blockNum;// 这个是要把目标文件分成的块数;
private long blockLength;// 每一块的大小
private String destBlockPath;// 分割后的文件的存放的位置
private List<String> blockName;
public splitFile() {
blockName = new ArrayList<String>();
}
public splitFile(String filePath, String destBlockPath) {// 如果不声明每一块的长度 那么默认为是1024
this(filePath, destBlockPath, 1024);// 这个是对下面这个构造器的调用
}
public splitFile(String filePath, String destBlockPath, long blockLength) {
this();// 对无参构造的调用
this.filePath = filePath;
this.destBlockPath = destBlockPath;
this.blockLength = blockLength;
init();
}
/*
* 初始化操作 计算块数,确定文件名;
*/
void init() {
// 这里是保持程序的健壮性
File src = new File(filePath);
if (filePath == null || !(src.exists())) {// 如果文件的路径为空 或者 是文件不存在 就没必要处理了 直接进行返回
return;
}
if (src.isDirectory()) {// 如果将要分割的文件是一个文件夹 那么也不进行操作
return;// return 有两个作用一个是结束程序另一个是返回一个值 这里的作用就是结束程序
}
this.fileName = src.getName(); // 将要分个文件的名称,长度 存放起来
this.length = src.length();
if (blockLength > src.length()) {// 修正每块的大小
blockLength = src.length();
}
// 计算出应该分成的块数
blockNum = (int) (Math.ceil(length * 1.0 / blockLength));// 看一下api 注意一下他的参数应该是一个double 类型的
// 确定文件的路径 我们分割后文件的路径是将他们存放到一个List容器中了
for (int i = 0; i < blockNum; i++) {
blockName.add(destBlockPath + "/" + this.fileName + ".part" + i);
}
}
/**
* 文件的 分割输入输出 文件的拷贝
*
* @param num
* 文件的第几块
* @param startPoint
* 文件开始的那个点
* @param reallyLength
* 文件的实际大小
* @throws IOException
*
*/
private void splitDetail(int num, long startPoint, long reallyLength) throws IOException {
File src = new File(filePath);
File dest = new File(blockName.get(num));
// 2、选择流
RandomAccessFile raf = null; // 输入流
BufferedOutputStream bos = null; // 输出流
try {
raf = new RandomAccessFile(src, "r");
bos = new BufferedOutputStream(new FileOutputStream(dest));
// 读取文件
raf.seek(startPoint);
// 缓冲区
byte[] flush = new byte[1024];
// 接收长度
int len = 0;
while (-1 != (len = raf.read(flush))) {
if (reallyLength - len >= 0) { // 查看是否足够
// 写出
bos.write(flush, 0, len);
reallyLength -= len; // 剩余量
} else { // 写出最后一次的剩余量
bos.write(flush, 0, (int) reallyLength);
break;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
bos.close();
raf.close();
}
}
public static void main(String[] args) {
splitFile split = new splitFile("F:/testIO/1.txt","F:/testIO",50);
System.out.println(split.blockNum);
}
}
5.IO流的总结:
下图为重点流:
下图为流的总结:
我们学过IO流之后要掌握以下操作: