公司無聊想做一個(gè)文件傳輸巫财,斷點(diǎn)續(xù)傳功能,然后呢哩陕,就寫了一個(gè)demo版平项,
我不會(huì)講解代碼赫舒,但是我會(huì)寫代碼
https://gitee.com/heixiaomas_admin/file_transfer_system.git
基于netty的文件拆分,簡(jiǎn)易文字聊天闽瓢,分片傳輸接癌,文件合并,重新連接鸳粉,續(xù)發(fā)分片demo
序列化采用jboss的marshalling-serial
代碼運(yùn)行效果如圖(聊天過程自己和自己發(fā)文件)
image.png
image.png
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="個(gè)人簡(jiǎn)歷.docx";
private static String newfilename="個(gè)人簡(jiǎn)歷_new.docx";
//拆分大小,請(qǐng)保證拆分大小保證大于1 kB扔涧,大小自己控制
private static final int count = 1;
public static void main(String[] args) throws Exception {
//保存拆分
saveFile();
//進(jìn)行合并
getMerge();
}
/**
* 創(chuàng)建指定大小的文件
*
* @param size
*/
public static void createBigFile(long size) {
Path filePath = Paths.get("E:\\test\\個(gè)人簡(jiǎn)歷_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);
//計(jì)算前部整體
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();
}
//計(jì)算尾巴
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");
//拆分文件名,拆分份數(shù)届谈,拆分大小枯夜,最后一次拆分大小,被拆分文件總大小
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(",");
//創(chuàng)建一個(gè)空的文件
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();
}
}