public static void main(String[] args) throws IOException {
File sourceFile = new File("D:\\44.mp4")
String chunkFolder = "D:\\IDM\\videos\\chunks\\"
File f = new File(chunkFolder)
if (!f.exists()){
f.mkdirs()
}
long shareSize = 1024 * 1024 * 10
System.out.println("分片大小: " + shareSize)
try (RandomAccessFile randomAccessFileReader = new RandomAccessFile(sourceFile, "r")
ByteBuffer buffer = ByteBuffer.allocate(1024)
long total = (long) Math.ceil(sourceFile.length() * 1.0 / shareSize)
System.out.println("分片总数: " + total)
for (int i = 0
File chunkFile = new File(chunkFolder + i)
System.out.println("分片: " + (i + 1) + ", chunkFile: " + chunkFile.getName())
try (RandomAccessFile randomAccessFileWriter = new RandomAccessFile(chunkFile, "rw")
FileChannel fileChannelWriter = randomAccessFileWriter.getChannel()) {
int len
buffer.clear()
while ((len=fileChannelReader.read(buffer)) != -1) {
//改为读模式
buffer.flip()
fileChannelWriter.write(buffer)
//改为写模式
buffer.compact()
//如果分片的大小>=分片的大小,读下一块
if (chunkFile.length() >= shareSize) {
break
}
}
} catch (IOException e) {
e.printStackTrace()
}
}
} catch (IOException e) {
e.printStackTrace()
}
//合并文件
mergeFile(new File(chunkFolder))
}
/**
* 合并块文件
* @param chunkFolder
*/
public static void mergeFile(File chunkFolder) throws IOException {
//块文件夹下文件列表
File[] files = chunkFolder.listFiles()
assert files != null
List<File> fileList = Arrays.stream(files).sorted(
Comparator.comparing(o -> Long.valueOf(o.getName())))
.collect(Collectors.toList())
//合并的文件
File mergeFile = new File("D:\\IDM\\videos\\chunks\\java_merge.mp4")
//创建新文件
boolean success = mergeFile.createNewFile()
//创建写对象
RandomAccessFile randomAccessFileWriter = new RandomAccessFile(mergeFile, "rw")
byte[] bytes = new byte[1024]
for (int i = 0
File chunkFile = fileList.get(i)
logger.info("合并------>分片:{},chunkFile:{}", i + 1, chunkFile.getName())
RandomAccessFile randomAccessFileReader = new RandomAccessFile(chunkFile, "r")
int len
while ((len = randomAccessFileReader.read(bytes)) != -1) {
randomAccessFileWriter.write(bytes, 0, len)
}
randomAccessFileReader.close()
}
randomAccessFileWriter.close()
Arrays.stream(files).forEach( f->{
f.delete()
} )
}
@GetMapping("/t")
public String test() {
String filePath = "D:\testdata.zip";
String fileName = "testdata.zip";
File sourceFile = new File(filePath);
long shareSize = 1024 * 1024;
String path = "D:\test\";
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
long total = 0;
try (RandomAccessFile randomAccessFileReader = new RandomAccessFile(sourceFile, "r"); FileChannel fileChannelReader = randomAccessFileReader.getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
total = (long) Math.ceil(sourceFile.length() * 1.0 / shareSize);
System.out.println("分片总数: " + total);
byte[] bytes = new byte[1024];
for (int i = 0; i < total; i++) {
File chunkFile = new File(path + i);
log.info("分片:{},chunkFile:{}", i + 1, chunkFile.getName());
RandomAccessFile randomAccessFileWriter = new RandomAccessFile(chunkFile, "rw");
int len;
while ((len = randomAccessFileReader.read(bytes)) != -1) {
randomAccessFileWriter.write(bytes, 0, len);
if (chunkFile.length() >= shareSize) {
break;
}
}
randomAccessFileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
long start = 0;
for (int i = 0; i < total; i++) {
long chunkStart = start + i * shareSize;
File file = new File(path + i);
FileItem item = new DiskFileItemFactory().createItem("file"
, MediaType.MULTIPART_FORM_DATA_VALUE
, true
, file.getName());
try (InputStream input = new FileInputStream(file);
OutputStream os = item.getOutputStream()) {
IOUtils.copy(input, os);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid file: " + e, e);
}
MultipartFile chunkFile = new CommonsMultipartFile(item);
fileService.resumeUpload(chunkFile, chunkStart, fileName);
}
return "ok";
}
public String resumeUpload(MultipartFile file, long start, String fileName) {
try {
File directory = new File(UPLOAD_DIR);
if (!directory.exists()) {
directory.mkdirs();
}
File targetFile = new File(UPLOAD_DIR + fileName);
RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw");
FileChannel channel = randomAccessFile.getChannel();
channel.position(start);
channel.transferFrom(file.getResource().readableChannel(), start, file.getSize());
channel.close();
randomAccessFile.close();
return "上传成功";
} catch (Exception e) {
System.out.println("上传失败: " + e.getMessage());
return "上传失败";
}
}