首页 > 编程语言 >java实现大文件多线程上传案例

java实现大文件多线程上传案例

时间:2023-10-16 18:33:48浏览次数:40  
标签:raf java long start end 多线程 上传 SIZE

当机器内存大小为4G,需要上传一个大小为50G的文件时,为了避免内存溢出,可以采用分片上传的方式,即将大文件切分成多个小片段进行并发上传。以下是一个详细的方案和代码实现示例:

方案说明:

将大文件切分成多个大小适当的片段(例如每个片段大小为100MB)。
创建一个线程池来管理并发上传任务,控制同时进行的上传任务数量。
每个线程负责上传一个片段,通过设置上传的起始位置和结束位置来读取并上传对应的片段数据。
在上传过程中,通过使用RandomAccessFile或者其他适合的文件读取方式,避免将整个文件加载到内存中。
代码实现:

import java.io.File;
import java.io.RandomAccessFile;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileUploader {
private static final int CHUNK_SIZE = 100 * 1024 * 1024; // 100MB
private static final int THREAD_POOL_SIZE = 10;

public static void main(String[] args) {
String filePath = "path/to/large/file"; // 大文件路径
File file = new File(filePath);
long fileSize = file.length();
long numChunks = fileSize / CHUNK_SIZE;

ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
for (int i = 0; i < numChunks; i++) {
long start = i * CHUNK_SIZE;
long end = (i + 1) * CHUNK_SIZE - 1;

executor.execute(new UploadTask(raf, start, end));
}

// 处理剩余的片段
if (fileSize % CHUNK_SIZE != 0) {
long start = numChunks * CHUNK_SIZE;
long end = fileSize - 1;

executor.execute(new UploadTask(raf, start, end));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}

static class UploadTask implements Runnable {
private RandomAccessFile raf;
private long start;
private long end;

public UploadTask(RandomAccessFile raf, long start, long end) {
this.raf = raf;
this.start = start;
this.end = end;
}

@Override
public void run() {
try {
byte[] chunk = new byte[(int) (end - start + 1)];

synchronized (raf) {
raf.seek(start);
raf.readFully(chunk);
}

// 调用上传接口进行上传操作
uploadChunk(chunk);
} catch (Exception e) {
e.printStackTrace();
}
}

private void uploadChunk(byte[] chunk) {
// 实现上传逻辑,将chunk上传到目标位置
// 可以使用HttpClient或其他上传工具进行上传
// ...
}
}
}


以上代码实现了将大文件分片上传的逻辑。通过使用线程池管理并发上传任务,每个任务负责上传一个片段。在上传过程中,通过随机访问文件方式,避免将整个文件加载到内存中,从而避免内存溢出的问题。

参考文章:http://blog.ncmem.com/wordpress/2023/10/16/java%e5%ae%9e%e7%8e%b0%e5%a4%a7%e6%96%87%e4%bb%b6%e5%a4%9a%e7%ba%bf%e7%a8%8b%e4%b8%8a%e4%bc%a0%e6%a1%88%e4%be%8b/

欢迎入群一起讨论

 

 

标签:raf,java,long,start,end,多线程,上传,SIZE
From: https://www.cnblogs.com/songsu/p/17768064.html

相关文章

  • java批量执行atax同步MySQL表时出现卡住问题处理
    中断问题和datax中自带的MySQLjar包版本有关,更换后即可。背景:有个需求需要把服务器上的mysql业务库数据同步到另一台服务器上,我选择了datax来做批量同步操作。现象:java批量执行的代码写好后,在自己电脑(win10)执行没问题,换了一台电脑(也是windowsserver2019),报以下错误://执行以......
  • 详解Java HashMap
    HashMap介绍HashMap遍历方式HashMap的遍历,大体上可分为4类,而每种类型下又有不同的实现方式,总共的遍历方式可分为7种:迭代器遍历:使用迭代器对EntrySet遍历;使用迭代器对KeySet遍历;foreach遍历:使用foreach对EntrySet遍历;使用foreach对KeySet遍历;lambda表达式遍历;stre......
  • java程序的运行流程(jdk,jre,jvm的关系)
    资料来源于第8课:https://www.bilibili.com/video/BV1o841187iP?p=8&spm_id_from=pageDriver&vd_source=c3a656550cf5d38944e8878bb7026cbc1.我们手写的java 代码为.java后缀文件储存在src当中。2.经过jdk中的bin中的javac.exe文件编译出.class文件的字节码。3.字节码储存在ou......
  • java中接口的实现方式
    目录Java8接口初始化的几种场景通过接口实现类的方式实现1.定义接口2.接口实现3.测试方法通过匿名内部类的来实现接口实现3.测试方法通过方法的引用1.实现通过箭头函数Lambda表达式的方式1.定义接口2.接口实现3.测试方法将接口作为方法参数1.定义一个方法2.调用方法并......
  • Java 中的异常处理
    在Java中,异常是中断程序正常流程的事件。当发生意外情况时,会引发异常。如果没有正确的处理,这些异常可能会使您的程序崩溃。Java提供了强大的异常处理机制,确保您的代码能够优雅地处理意外情况。异常可能由多种因素引起,例如:用户输入错误硬件故障网络连接错误数据库错误编程......
  • Java拾贝第三天——面向对象2
    继承性面向对象三大特性:封装性,继承性,多态性。继承的作用是避免出现大幅度的相同代码,提高代码的复用性。//现有一个Person类,拥有name,age属性classPerson{privateStringname;privateintage;//构造方法和setter,getter现在有一个Student类,它和Person类的属性......
  • Java Assert断言使用
    目录断言所谓的assertion,是jdk1.4后加入的新功能。作用它主要使用在代码开发和测试时期,用于对某些关键数据的判断,如果这个关键数据不是你程序所预期的数据,程序就提出警告或退出。后续当软件正式发布后,可以取消断言部分的代码。java中使用assert作为断言的一个关......
  • java web
    0.了解maven1.了解http协议2.了解tmcat的作用3.了解请求响应4.了解分层解耦5.了解servlet原理Maven为java世界引入了一个新的依赖管理系统jar包管理jar包升级时修改配置文件即可......
  • Java设计模式
    七大设计原则开闭原则:是指一个软件实体如类、模块和函数应该对扩展开放,对修改关闭依赖倒置原则:是指设计代码结构时,高层模块不应该依赖底层模块,二者都应该依赖其抽象而不依赖于具体。单一职责原则:是指一个Class/Interface/Method只负责一项职责。接口隔离原则:是指用多个专......
  • .NET 上传文件到华为云OBS
    一、创建一个HuaWeiOBS类,作为数据传递的对象。1publicclassHuaWeiOBS2{3publicstringAK{get;set;}4publicstringSK{get;set;}5///<summary>6///OBS桶终结点7///</summary>8publ......