java文件拆分合并,基于Netty的文件断点续传,分片传输
2019-05-08 本文已影响0人
黑小马_
公司无聊想做一个文件传输,断点续传功能,然后呢,就写了一个demo版,
我不会讲解代码,但是我会写代码
https://gitee.com/heixiaomas_admin/file_transfer_system.git
基于netty的文件拆分,简易文字聊天,分片传输,文件合并,重新连接,续发分片demo
序列化采用jboss的marshalling-serial
代码运行效果如图(聊天过程自己和自己发文件)


import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;
public class Main {
private static String path="E:/test/";
private static String filename="个人简历.docx";
private static String newfilename="个人简历_new.docx";
//拆分大小,请保证拆分大小保证大于1 kB,大小自己控制
private static final int count = 1;
public static void main(String[] args) throws Exception {
//保存拆分
saveFile();
//进行合并
getMerge();
}
/**
* 创建指定大小的文件
*
* @param size
*/
public static void createBigFile(long size) {
Path filePath = Paths.get("E:\\test\\个人简历_new.docx");
try {
if (!Files.exists(filePath)) {
Files.createFile(filePath);
}
} catch (IOException e1) {
e1.printStackTrace();
}
ByteBuffer buffer = ByteBuffer.allocate(1);
try (FileChannel fileChannel = FileChannel.open(filePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
fileChannel.position(size-1);
fileChannel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 拆分逻辑
*
* @throws Exception
*/
public static void saveFile() throws Exception {
RandomAccessFile randomAccessFile = new RandomAccessFile(path+filename, "r");
FileChannel channel = randomAccessFile.getChannel();
long size = channel.size();
long l = size / 1024;
if (l > count) {
System.out.println(l);
//计算前部整体
int i;
for (i = 0; i < l / count; i++) {
byte[] files = getFiles(randomAccessFile, randomAccessFile.getFilePointer(), count*1024);
FileOutputStream out = new FileOutputStream(path+filename+"." + (i + 1) + ".tmp");
out.write(files);
out.flush();
out.close();
}
//计算尾巴
long l1 = size - ((size / (count*1024)) * count*1024);
System.out.println(l1);
if (l1 > 0) {
byte[] files = getFiles(randomAccessFile, randomAccessFile.getFilePointer(), (int) l1);
FileOutputStream out = new FileOutputStream(path+filename+"." + (i + 1) + ".tmp");
out.write(files);
out.flush();
out.close();
}
FileOutputStream out = new FileOutputStream(path+"拆分说明.tmp");
//拆分文件名,拆分份数,拆分大小,最后一次拆分大小,被拆分文件总大小
out.write((filename+"," + (i + 1) + "," + count + "," + l1 + "," + size).getBytes());
out.flush();
out.close();
randomAccessFile.close();
}
}
/**
* 拆分文件
*
* @param file
* @param seek
* @param count
* @return
* @throws Exception
*/
public static byte[] getFiles(RandomAccessFile file, long seek, int count) throws Exception {
file.seek(seek);
byte[] bytes = new byte[count];
file.read(bytes);
return bytes;
}
/**
* 合并
*/
public static void getMerge() throws Exception {
FileInputStream inputStream = new FileInputStream(path+"拆分说明.tmp");
FileChannel channel = inputStream.getChannel();
byte[] bytes = new byte[(int) channel.size()];
inputStream.read(bytes);
String string = new String(bytes);
String[] split = string.trim().split(",");
//创建一个空的文件
createBigFile(Long.parseLong(split[split.length - 1]));
RandomAccessFile file = new RandomAccessFile(path+newfilename, "rw");
for (int i = 0; i < Integer.parseInt(split[1]); i++) {
System.out.println("拆分保存路径----》"+path + split[0] + "." + (i + 1) + ".tmp");
FileInputStream fin = new FileInputStream(path + split[0] + "." + (i + 1) + ".tmp");
byte[] byt;
//合并尾部文件
if (i == Integer.parseInt(split[1]) - 1) {
byt = new byte[Integer.parseInt(split[3])];
} else {
byt = new byte[Integer.parseInt(split[2]) * 1024];
}
fin.read(byt);
file.seek(file.getFilePointer());
file.write(byt);
}
file.close();
}
}