断点上传文件的前置知识,用io流实现文件分块与合并。
一、文件分块
/**
* 文件分块
*
* @param sourceFile 源文件
* @param targetDir 分块文件存放目录
*/
public static void Chunk(String sourceFile, String targetDir) {
// 准备文件
File file = new File(sourceFile);
if (!file.exists()) {
System.out.println("源文件不存在");
return;
}
//准备输入流读取文件,并且分块写入到指定目录
RandomAccessFile randomAccessFile = null;
try {
// 随机流,用于读取文件到内存,并且写入文件到磁盘
randomAccessFile = new RandomAccessFile(file, "rw");
// 分块大小 此处为1M
long chunkSize = 1024 * 1024 * 1;
// 每次读取的字节数
byte[] bytes = new byte[1024];
// 分块数 向上取整
long ceil = (long) Math.ceil(randomAccessFile.length() * 1.0 / chunkSize);
// 分块文件放在指定目录
File dir = new File(targetDir);
if (!dir.exists()) {
dir.mkdirs();
}
int len = -1;
for (int i = 0; i < ceil; i++) {
File temp = new File(targetDir + "\\" + i);
RandomAccessFile randomAccessFile1 = new RandomAccessFile(temp, "rw");
while ((len = randomAccessFile.read(bytes)) != -1) {
randomAccessFile1.write(bytes, 0, len);
if (temp.length() >= chunkSize) {
break;
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (randomAccessFile != null) {
try {
randomAccessFile.close();
System.out.println("分块成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、文件合并
/**
* @param sourceDir 分块文件目录
* @param fileName 合并文件名,需要带上后缀
*/
public static void Merge(String sourceDir, String fileName) {
// 找到源文件路径,循环所有的分块文件,输出到一个文件中
File file = new File(sourceDir);
if (!file.exists()) {
System.out.println("目录不存在");
return;
}
File[] files = file.listFiles();
if (files.length == 0) {
System.out.println("目录中没有文件");
}
RandomAccessFile randomAccessFile = null;
try {
// 合并的文件放在分块目录中
randomAccessFile = new RandomAccessFile(sourceDir + "\\" + fileName, "rw");
// 确保合并的顺序 分块是0-n,要确保合并顺序
List<File> list = Arrays.asList(files);
Collections.sort(list, (a, b) -> Integer.valueOf(a.getName()) - Integer.valueOf(b.getName()));
RandomAccessFile randomAccessFile1 = null;
for (File temp : list) {
randomAccessFile1 = new RandomAccessFile(temp, "rw");
int len = -1;
byte[] bytes = new byte[1024];
while ((len = randomAccessFile1.read(bytes)) != -1) {
randomAccessFile.write(bytes, 0, len);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
randomAccessFile.close();
System.out.println("合并成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}