首页 > 技术文章 > 七、java操作swift对象存储(动态大对象)

yclh 2021-08-03 19:32 原文

系列导航

一、swift对象存储环境搭建

二、swift添加存储策略

三、swift大对象--动态大对象

四、swift大对象--静态态大对象

五、java操作swift对象存储(官网样例)

六、java操作swift对象存储(resultful方式实现)

七、java操作swift对象存储(动态大对象)

八、java操作swift对象存储(静态大对象)

    前面讲了如何使用swift的动态大对象那么java如何操作呢?如下的例子是我自己写的不是官网的(官网的没找到)

一、依赖

   与  六、java操作swift对象存储(resultful方式实现)  一样这里就不重复了。

 

二、重要方法类DynamicLargeObject.java

package largeobject;

import java.io.File;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.apache.http.Header;
import base.ResultFulBase;
import largeobject.tool.CutFileUtil;


//动态大对象操作
public class DynamicLargeObject {
    
     //访问swift的url地址
     public static String X_Storage_Url = "";
     
     //访问swift的令牌
     public static String X_Auth_Token = "";
    
     public static ResultFulBase resultFulBase = null;
     
     public DynamicLargeObject(ResultFulBase resultFulBase){
         X_Storage_Url = resultFulBase.X_Storage_Url;
         X_Auth_Token = resultFulBase.X_Auth_Token;
         this.resultFulBase = resultFulBase;
     }
    
     //上传动态大对象 
    /* 参数说明
     * objectContainerName:存储对象分块的容器名称(实际上所有的段都可以在不同的容器里)
     * maniFestContainerName:存储manifest对象的容器
     * FilePath:上传的文件路径
     * objectName:上传后的对象名称
     * MBSize:切割文件的大小(单位MB)
     */
    public static  void upload_Dynamic_large_object(String objectContainerName,String maniFestContainerName,String FilePath,String objectName,long MBSize ){
        CutFileUtil cutFileUtil = new CutFileUtil();
        Long  mbSzie = MBSize*1024*1024;
        File file = new File(FilePath);
        String fileName = file.getName();
        String path  = file.getParent()+"//";
        
        int count =0 ;
        count = cutFileUtil.cutFileBySize(FilePath, mbSzie, path );
        
        System.out.println("FilePath:"+FilePath);
        System.out.println("path:"+path);
        System.out.println("fileName:"+fileName);
 
        
        JSONArray jsonArray = new JSONArray();
        //上传可以改为多线程 获取信息单独出来
        for(int i =0;i<count;i++ ){
            resultFulBase.create_object(objectContainerName,objectName+"/"+i+"-"+fileName ,path +i+"-"+fileName );
            String partFilePath = path+i+"-"+fileName;
            
            //删除上传过的 切割文件
            File partFile = new File(partFilePath);
            partFile.delete();
        }
 
        create_Dynamic_Manifest_object(objectContainerName,maniFestContainerName,objectName);
  
    }
    
    
    //动态大文件Manifest保存
    public static  void create_Dynamic_Manifest_object(String containerName,String maniFestContainerName ,String objectName){
        try {
            HttpPut req = new HttpPut(X_Storage_Url+ "/"+maniFestContainerName +"/"+objectName);
            req.addHeader("X-Auth-Token", X_Auth_Token);
 
            req.addHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
            req.addHeader("X-Object-Manifest",   containerName+"/"+objectName+"/");
            
           //好像不是必须的
          //req.addHeader("Content-Transfer-Encoding", "binary");
 
            DefaultHttpClient httpclient = new DefaultHttpClient();
            HttpResponse rsp = httpclient.execute(req);

            System.out.println("----------------------------------------");
            System.out.println(rsp.getStatusLine());
            Header[] headers = rsp.getAllHeaders();
            for (int i = 0; i < headers.length; i++) {
                System.out.println(headers[i]);
            }
            System.out.println("----------------------------------------");

        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

 三、数据切割类CutFileUtil.java

package largeobject.tool;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <功能简要> <br>
 * <切割文件工具>
 *
 * @Author yc
 * @since
 */
public class CutFileUtil {

    
    
    public static void main(String[] args) throws Exception {
        CutFileUtil cutFileUtil = new CutFileUtil();
        int count =0 ;
        cutFileUtil.cutFileBySize("E://1.jpg", new Long(30000), "E://1/" );
    }
    
    /**
     * @param filePath 文件所在主机的路径 例:/home/gyt/nginx.tar
     * @param byteSize 拆分文件字节大小
     * @param saveAddr 拆分后的文件保存目录  /homt/gyt/
     * @return
     */
    public int  cutFileBySize(String filePath, Long byteSize, String saveAddr  ){
        List<String> fileNames = new ArrayList<String>();
        File file = new File(filePath);
        //计算总共段数
        int count = (int) Math.ceil(file.length()/(double)byteSize);
        int countLen = (count +"").length();
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(count * 2);
        
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,4,1,TimeUnit.SECONDS, workQueue );
        
        //ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,4,1,TimeUnit.SECONDS,new ArrayBlockingQueue<>(count * 2));
        
        
        //时间戳
        String timeStamp = String.valueOf(System.currentTimeMillis());

        for (int i = 0; i < count; i++) {
            //分段文件名
           // String fileName = timeStamp + "-" + leftPad((i+1) +"", countLen, '0') + "-" +file.getName();
            String fileName =    i+ "-" +file.getName();
            threadPoolExecutor.execute(new SplitRunnable(byteSize.intValue(), fileName, file, i*byteSize, saveAddr));
            fileNames.add(fileName);
        }
        threadPoolExecutor.shutdown();
        while (true){
            if (threadPoolExecutor.isTerminated()){
                return count;
            }
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        
    }

    public static String leftPad(String str, int length, char ch){
        if (str.length() >= length){
            return str;
        }
        char[] chs = new char[length];
        Arrays.fill(chs, ch);
        char[] src = str.toCharArray();
        System.arraycopy(src, 0, chs, length - src.length, src.length);
        return new String(chs);
    }

    private class SplitRunnable implements Runnable{
        int byteSize;
        String fileName;
        File originFile;
        Long startPos;
        String currentWorkDir;

        public SplitRunnable(int byteSize, String fileName, File originFile, Long startPos, String currentWorkDir) {
            this.byteSize = byteSize;
            this.fileName = fileName;
            this.originFile = originFile;
            this.startPos = startPos;
            this.currentWorkDir = currentWorkDir;
        }

        public void run(){
            RandomAccessFile randomAccessFile = null;
            OutputStream outputStream = null;
            try {
                randomAccessFile = new RandomAccessFile(originFile, "r");
                byte[] b = new byte[byteSize];
                randomAccessFile.seek(startPos); //移动指针到每“段”开头
                int s = randomAccessFile.read(b);
                outputStream = new FileOutputStream(currentWorkDir+fileName);
                outputStream.write(b, 0 , s);
                outputStream.flush();
                b= null;
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                if (outputStream !=null){
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                if (randomAccessFile !=null){
                    try {
                        randomAccessFile.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

 

 

四、调用的主类DynamicLargeObjectMain.java

package mian;

import largeobject.DynamicLargeObject;
import base.ResultFulBase;

//动态大对象上传调用
public class DynamicLargeObjectMain {
    public static void main(String[] args) {
        
        //连接到swift获得令牌
        ResultFulBase resultFulBase = new ResultFulBase("192.168.0.1","8080","admin:admin","admin");
        
        //初始化动态大对象的操作类
        DynamicLargeObject dynamicLargeObjectd = new DynamicLargeObject(resultFulBase);
        
        //上传一个动态大对象
        //注:E://1/1.zip 是一个5M多的文件, 切割大小为3M每块
        dynamicLargeObjectd.upload_Dynamic_large_object("SegmentContainer","maniFestContainer","E://1/1.zip",  "1.zip",new Long(3) );
 
        //下载上传上去的大对象
        resultFulBase.get_container_object("maniFestContainer","1.zip","E:\\mylarge.zip");
        
    }
}

   

推荐阅读