发表于: 2018-03-27 22:03:06

1 662


今天完成的事情:
尝试从阿里云获取文件,然后上传到七牛云。
程序运行结果如下:
七牛云文件管理显示如下:
阿里云文件显示如下:
逻辑代码如下:
// 创建OSSClient实例
OSSObject ossObject = ossClient.getObject(bucketName, "121.kpg");
// 读Object内容
logger.info("获取文件开始!");
InputStream in = ossObject.getObjectContent();
QiniuUtils.up(in, "121.kpg");
//阿里的文件说,在完成传输以后要关闭对象流,避免资源泄露。
ossObject.getObjectContent().close();
// 关闭client
ossClient.shutdown();
阿里云给的案例是这样的:
也就是客户端获取到对象以后,可以通过获取的对象直接获取到流。然后将流转化成InputStreamReader对象,然后再转化成BufferedReader对象,最后将BufferedReader一行一行的读取出来转化成String形式,很可惜,转化出来的都是乱码。不知道能不能输出为二进制形式。
感觉就像是以项目为中点,在两个服务器之间建立了一个流的通道,完成文件从一个服务器流转到另一个服务器的传输。
短暂完成单个文件的传输,但是怎么将两个存储空间的文件全部传输到另一个空间?
首先遍历七牛云空间下的所有文件:
代码如下:
//实例化一个BucketManager对象
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
    //调用listFiles方法列举指定空间的指定文件
    //参数一:bucket    空间名
    //参数二:prefix    文件名前缀
    //参数三:marker    上一次获取文件列表时返回的 marker
    //参数四:limit     每次迭代的长度限制,最大1000,推荐值 100
    //参数五:delimiter 指定目录分隔符,列出所有公共前缀(模拟列出目录)。缺省值为空字符串
    FileListing fileListing = bucketManager.listFiles(bucket, null, null, 10, null);
    FileInfo[] items = fileListing.items;
    for (FileInfo fileInfo : items) {
        logger.info(fileInfo.key);
    }
} catch (QiniuException e) {
    //捕获异常信息
    Response r = e.response;
    logger.info(r.toString());
}
然后根据文件名获取到对应的七牛云下载链接:
代码如下:
public static String down(String fileName) throws IOException {
    String encodedFileName = URLEncoder.encode(fileName, "utf-8");
    String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
    return finalUrl;
}
效果如下图:
这就是七牛云蛋疼的地方了,七牛他无法直接从存储空间去获得对象,需要先调出文件的下载链接,然后要通过链接去下载文件。
所以又从网上找了一份将url转化成文件流的办法:
URL url = new URL(imgUrl);// 构造URL
URLConnection con = url.openConnection();// 打开连接
return con.getInputStream();
然后将文件流传递给阿里云的文件流上传方法:
ossClient.putObject(bucketName, filename, inputStream);
测试方法如下:
//创建阿里云工具类实体对象
OSSUtil ossUtil = new OSSUtil();
//通过七牛云工具类获取七牛云文件列表
FileInfo[] info = QiniuUtils.Qniuall();
//遍历文件列表,得到各个文件的文件名
for (FileInfo fileInfo : info) {
    logger.info(fileInfo.key);
    //通过文件名去获取到七牛云的下载链接
    String url = QiniuUtils.down(fileInfo.key);
    logger.info(url);
    //将链接转化成输入流
    InputStream in = urlsa.urldown(url);
    logger.info(in);
    //将流传递给阿里云上传方法,实现文件的上传。
    ossUtil.putFiles(fileInfo.key, in);
    in.close();
}
//关闭客户端
ossUtil.shutdownClient();
最终结果如下:


接下来就是阿里云上传到七牛云

代码如下:
遍历阿里云所有文件:
// 构造ListObjectsRequest请求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
// 列出Object
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
return listing;
通过阿里云文件名获取文件流:
// 创建OSSClient实例
OSSObject ossObject = ossClient.getObject(bucketName, filename);
// 读Object内容
logger.info("获取文件开始!" + filename);
InputStream in = ossObject.getObjectContent();
logger.info(in);
return in;
通过七牛云流方法上传并获取到下载链接:
String finalUrl = null;
UploadManager uploadManager = new UploadManager(cfg);
//默认不指定key的情况下,以文件内容的hash值作为文件名,先以上传时间为文件名
String key = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "." + uptype;
logger.info(inputStream);
Response response = uploadManager.put(inputStream, key, upToken, null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
String encodedFileName = null;
try {
    encodedFileName = URLEncoder.encode(putRet.key, "utf-8");
} catch (IOException e) {
    e.printStackTrace();
}
finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
logger.info("finalUrl\t" + finalUrl);
return finalUrl;
但上面有个问题,就是从阿里云上传到七牛云的文件,文件名都会被在前面添加一次时间。这样,两边的文件名不一致,数据库无法保持一致性。
明天计划的事情:
遇到的问题:
1.程序启动后,报找不到方法的异常。
改动后端方法之后,并未刷新jrebel,前端调用的方法与后端已编译的方法不对应。重新刷新jrebel后解决。
2.关于乱码问题。
之前看师弟日报,只添加了网页和web.xml的字符串设置,就完成了正常字符的转换,就撤了在Tomcat的设置,然后控制台输出就出了问题。
只好重新在Tomcat添加-Dfile.encoding=UTF-8来处理控制台乱码问题。


收获:

1.中午因为客户端异常的问题,和牛师兄讨论一下问题和解决方案,对面向对象,代码编写有了一个更深的体会。

首先,看到重复的代码,在实现功能的前提下,回过头再好好考虑一下如何将重复代码提取出来,写成一个专门的方法。

进度:
任务开始时间:2018年03月18日
预计demo时间:2018年03月30日
禅道地址:http://task.ptteng.com/zentao/project-task-490.html



返回列表 返回列表
评论

    分享到