本篇文章记录了本人在实习期间所完成的任务:用华为云官方提供的Java开发文档,实现监控某一文件夹,进行自动把整个文件目录结构上传到华为云OBS。

本人也为刚毕业的实习生,若文章有什么问题还请指出,共同进步。

前提条件:已经有华为云账号并已经开通对象存储服务(OBS)如图:

华为云:https://activity.huaweicloud.com

java上传文件使用JAXBContext导入xml java上传文件到本地_华为

点击以后创建桶:

java上传文件使用JAXBContext导入xml java上传文件到本地_spring_02

点击我的凭证查看本次所要使用到的华为云的ak,sk,endPoint(在建立的桶中查看)

java上传文件使用JAXBContext导入xml java上传文件到本地_intellij idea_03

点击访问秘钥

 

java上传文件使用JAXBContext导入xml java上传文件到本地_华为_04

没有秘钥的点击新建访问秘钥,下载Excel表格,里面就会有所需要的的ak,sk

java上传文件使用JAXBContext导入xml java上传文件到本地_intellij idea_05

Endpoint是根据自己选择地区不同而变换的

java上传文件使用JAXBContext导入xml java上传文件到本地_华为_06

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) {
            // 发生异常时可再次调用断点续传上传接口进行重新上传
        }
    }



将图中的该行放行就可以实现对于指定文件夹的极其目录的上传

java上传文件使用JAXBContext导入xml java上传文件到本地_java_07

小结:

        实现的原理很简单,是用轮询实现对指定的目录进行监控,监测到目录有变化就开始执行断点续传的方法体。

难点在于:

        1.华为云所提供的SDK无法直接实现目录结构的上传,本人在这里给定了绝对路径,然后对路径的字符串进行裁剪,最终实现了文件目录的整体上传。

·       2.对于文件是否完整的检验,华为云官方给出的是进行MD5的校验,但是本人在使用过程中并没有体会到该校验的功能性。

希望大家可以互相学习,提供更好的建议!