Endpoint是根据自己选择地区不同而变换的 endPoint格式为:https://+自己的Endpoint地址,例如:https://obs.cn-north-1.myhuaweicloud.com
在获取了ak,上课,endPont以后创建一个Java项目,我在这所使用的的为SpringBoot2.5.7,pom.xml代码如下: <properties> <java.version>1.8</java.version></properties><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.huaweicloud.sdk</groupId> <artifactId>huaweicloud-sdk-vpc</artifactId> <version>[3.0.40-rc, 3.1.0)</version> </dependency> <dependency> <groupId>com.huaweicloud</groupId> <artifactId>esdk-obs-java-bundle</artifactId> <version>[3.21.8,)</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.5.6</version> </dependency></dependencies>
util类:主要放的就是一些常用到的桶名,ak,sk,endPoint等
import com.obs.services.ObsClient;public class Util { //上传地址 private String endPoint = "https://obs.cn-north-1.myhuaweicloud.com"; //华为云ak private String ak = "JOORAQZFYBY8K6P93MPI"; //华为云sk private String sk = "RN2Nh067o4WiFNwjOhAUoWc3k0FzAhqI9QNChbEp"; //华为云桶名称 private String backName = "hzldata"; //华为云创建文件夹名称 private String createFileDirectory = ""; public String getCreateFileDirectory() { return createFileDirectory; } public void setCreateFileDirectory(String createFileDirectory) { this.createFileDirectory = createFileDirectory; } public String getBackName() { return backName; } public void setBackName(String backName) { this.backName = backName; } ObsClient obsClient = new ObsClient(ak,sk,endPoint); public Util() { } public String getEndPoint() { return endPoint; } public void setEndPoint(String endPoint) { this.endPoint = endPoint; } public String getAk() { return ak; } public void setAk(String ak) { this.ak = ak; } public String getSk() { return sk; } public void setSk(String sk) { this.sk = sk; }}
所用到的依赖: import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.*;
import java.security.NoSuchAlgorithmException;
轮询的代码实现:
public class UpApplication extends FileAlterationListenerAdaptor{
private boolean isCompletelyWritten(File file) {
RandomAccessFile stream = null;
try {
stream = new RandomAccessFile(file, "rw");
return true;
} catch (Exception e) {
System.out.println(e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
return false;
}
@Override
public void onStart(FileAlterationObserver fileAlterationObserver) {
//开启监听时默认调用的方法;一般不实现本方法。
}
@Override
public void onDirectoryCreate(File directory) {
/* 开启监听后发现有新目录被创建时需要做的事情 ;
* 但实际测试过程中发现,已有目录被更改时(包括自身文件夹名称更改、下级文件夹更改、下级文件更改),也会触发本方法 ;
*/
System.out.println("检测到[文件夹]【新增】"+directory.getAbsolutePath());
}
@Override
public void onFileCreate(File file) {
/* 开启监听后发现新增文件时需要做的事情 ;
*/
System.out.println("检测到[文件]【新增】"+file.getAbsolutePath());
try {
xc(file.getPath().replaceAll("\\\\", "/"), file.getAbsolutePath().replaceAll("\\\\", "/").substring(8));
} catch (IOException e) {
e.printStackTrace();
return;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return;
}
System.out.println("上传完成");
/*xc(file.getPath().replaceAll("\\\\","/"),file.getAbsolutePath().replaceAll("\\\\","/").substring(8));
System.out.println("上传完成");*/
}
public static void main(String[] args) {
//待观察的文件夹
String listenDiretory = "D:/data";
//轮询的时间间隔,单位毫秒
long intervalTime = 1000;
// 创建观察者对象,主要用于观察指定文件(或文件夹)及其子文件(或子文件夹)的变化 ;
/* 若不需要监听子文件夹,可以这样写: new FileAlterationObserver("E:/AAAA", FileFilterUtils.and(FileFilterUtils.fileFileFilter()), null);
*/
//FileAlterationObserver observer = new FileAlterationObserver("D:/data", FileFilterUtils.and(FileFilterUtils.fileFileFilter()), null);
FileAlterationObserver observer = new FileAlterationObserver(listenDiretory);
// 创建收听者对象(即自行实现FileAlterationListener接口的类),主要用于完成文件或文件夹变化后需要做的事情 ;
UpApplication listener = new UpApplication();
// 将收听者对象添加到观察者对象中,表示将观察到的文件或文件夹变化告知收听者
observer.addListener(listener);
// 创建监听者对象,将用于启动后轮询监听观察者对象
/* 第一个参数单位是毫秒,是监听的间隔;第二个参数就是绑定我们之前的观察对象。
* 若有多个目录需要同时监听和处理,则第二个参数可以写成数组形式:new FileAlterationMonitor(10000, new FileAlterationObserver[]{observer1,observer2,observer3});
* 若只有一个目录需要监听,则只需要传入已创建的观察对象observer:new FileAlterationMonitor(10000, observer);
*/
FileAlterationMonitor monitor = new FileAlterationMonitor(intervalTime, observer);
// 开始监听
try {
//开始监控,该方法每隔intervalTime毫秒调用一轮FileAlterationMonitor实现对象的方法,一定会默认执行onStart()和onStop()方法
monitor.start();
//启动程序后,在E:\AAAA文件夹下手动操作文件或文件夹即可在控制台查看打印信息。
System.out.println("\n开始监测文件夹:"+ listenDiretory );
} catch (Exception e) {
e.printStackTrace();
}
}
}
OBS断点续传的方法 //断点续传
public static void xc(String file,String objectKey) throws IOException, NoSuchAlgorithmException {
Util util = new Util();
// 设置待上传的本地文件,localfile为待上传的本地文件路径,需要指定到具体的文件名
UploadFileRequest request = new UploadFileRequest(util.getBackName(), objectKey);
// 计算并设置MD5值
ObjectMetadata metadata = new ObjectMetadata();
FileInputStream fis = new FileInputStream(file);
InputStream is = (InputStream)fis;
String contentMd5 = util.obsClient.base64Md5(is);
metadata.setContentMd5(contentMd5);
// 带MD5值上传文件
util.obsClient.putObject(util.getBackName(), objectKey, new File(file), metadata);
request.setUploadFile(file);
// 设置分段上传时的最大并发数
request.setTaskNum(10);
// 设置分段大小为10MB
request.setPartSize(100 * 1024 * 1024);
// 开启断点续传模式
request.setEnableCheckpoint(true);
try{
// 进行断点续传上传
CompleteMultipartUploadResult result = util.obsClient.uploadFile(request);
}catch (ObsException e) {
// 发生异常时可再次调用断点续传上传接口进行重新上传
}
}
将图中的该行放行就可以实现对于指定文件夹的极其目录的上传 小结:
实现的原理很简单,是用轮询实现对指定的目录进行监控,监测到目录有变化就开始执行断点续传的方法体。 难点在于: 1.华为云所提供的SDK无法直接实现目录结构的上传,本人在这里给定了绝对路径,然后对路径的字符串进行裁剪,最终实现了文件目录的整体上传。 · 2.对于文件是否完整的检验,华为云官方给出的是进行MD5的校验,但是本人在使用过程中并没有体会到该校验的功能性。 希望大家可以互相学习,提供更好的建议! |