Skip to content

Commit 0bcf24b

Browse files
committed
add list bucket v2 method in BucketManager.
1 parent 4106938 commit 0bcf24b

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed

src/main/java/com/qiniu/storage/BucketManager.java

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
package com.qiniu.storage;
22

3+
import com.google.gson.JsonNull;
4+
import com.google.gson.JsonObject;
35
import com.qiniu.common.Constants;
46
import com.qiniu.common.QiniuException;
57
import com.qiniu.http.Client;
68
import com.qiniu.http.Response;
79
import com.qiniu.storage.model.*;
810
import com.qiniu.util.*;
911

10-
import java.util.ArrayList;
11-
import java.util.Iterator;
12-
import java.util.Map;
13-
12+
import java.util.*;
1413

1514
/**
1615
* 主要涉及了空间资源管理及批量操作接口的实现,具体的接口规格可以参考
1716
* 参考文档:<a href="http://developer.qiniu.com/kodo/api/rs">资源管理</a>
1817
*/
1918
public final class BucketManager {
19+
2020
/**
2121
* Auth 对象
2222
* 该类需要使用QBox鉴权,所以需要指定Auth对象
@@ -27,7 +27,6 @@ public final class BucketManager {
2727
* Configuration 对象
2828
* 该类相关的域名配置,解析配置,HTTP请求超时时间设置等
2929
*/
30-
3130
private Configuration configuration;
3231

3332
/**
@@ -53,7 +52,6 @@ public BucketManager(Auth auth, Client client) {
5352
this.client = client;
5453
}
5554

56-
5755
/**
5856
* EncodedEntryURI格式,其中 bucket+":"+key 称之为 entry
5957
*
@@ -83,7 +81,6 @@ public static String encodedEntry(String bucket) {
8381
return encodedEntry(bucket, null);
8482
}
8583

86-
8784
/**
8885
* 获取账号下所有空间名称列表
8986
*
@@ -114,7 +111,6 @@ public void deleteBucket(String bucketname) throws QiniuException {
114111
* @return 该空间名下的domain
115112
* @throws QiniuException
116113
*/
117-
118114
public String[] domainList(String bucket) throws QiniuException {
119115
String url = String.format("%s/v6/domain/list?tbl=%s", configuration.apiHost(), bucket);
120116
Response r = get(url);
@@ -145,8 +141,14 @@ public FileListIterator createFileListIterator(String bucket, String prefix, int
145141
return new FileListIterator(bucket, prefix, limit, delimiter);
146142
}
147143

144+
private String listQuery(String bucket, String prefix, String marker, int limit, String delimiter) {
145+
StringMap map = new StringMap().put("bucket", bucket).putNotEmpty("marker", marker)
146+
.putNotEmpty("prefix", prefix).putNotEmpty("delimiter", delimiter).putWhen("limit", limit, limit > 0);
147+
return map.formString();
148+
}
149+
148150
/**
149-
* 根据前缀获取文件列表
151+
* 列举空间文件 v1 接口,返回一个 response 对象。
150152
*
151153
* @param bucket 空间名
152154
* @param prefix 文件名前缀
@@ -156,16 +158,69 @@ public FileListIterator createFileListIterator(String bucket, String prefix, int
156158
* @return
157159
* @throws QiniuException
158160
*/
161+
public Response listV1(String bucket, String prefix, String marker, int limit, String delimiter)
162+
throws QiniuException {
163+
String url = String.format("%s/list?%s", configuration.rsfHost(auth.accessKey, bucket),
164+
listQuery(bucket, prefix, marker, limit, delimiter));
165+
return get(url);
166+
}
167+
159168
public FileListing listFiles(String bucket, String prefix, String marker, int limit, String delimiter)
160169
throws QiniuException {
161-
StringMap map = new StringMap().put("bucket", bucket).putNotEmpty("marker", marker)
162-
.putNotEmpty("prefix", prefix).putNotEmpty("delimiter", delimiter).putWhen("limit", limit, limit > 0);
170+
Response response = listV1(bucket, prefix, marker, limit, delimiter);
171+
if (!response.isOK()) {
172+
throw new QiniuException(response);
173+
}
174+
FileListing fileListing = response.jsonToObject(FileListing.class);
175+
response.close();
176+
return fileListing;
177+
}
163178

164-
String url = String.format("%s/list?%s", configuration.rsfHost(auth.accessKey, bucket), map.formString());
165-
Response r = get(url);
166-
return r.jsonToObject(FileListing.class);
179+
/**
180+
* 列举空间文件 v2 接口,返回一个 response 对象。v2 接口可以避免由于大量删除导致的列举超时问题,返回的 response 对象中的 body 可以转换为
181+
* string stream 来处理。
182+
*
183+
* @param bucket 空间名
184+
* @param prefix 文件名前缀
185+
* @param marker 上一次获取文件列表时返回的 marker
186+
* @param limit 每次迭代的长度限制,推荐值 10000
187+
* @param delimiter 指定目录分隔符,列出所有公共前缀(模拟列出目录效果)。缺省值为空字符串
188+
* @return Response 返回一个 okhttp response 对象
189+
* @throws QiniuException
190+
*/
191+
public Response listV2(String bucket, String prefix, String marker, int limit, String delimiter)
192+
throws QiniuException {
193+
String url = String.format("%s/v2/list?%s", configuration.rsfHost(auth.accessKey, bucket),
194+
listQuery(bucket, prefix, marker, limit, delimiter));
195+
return get(url);
196+
}
197+
198+
public FileListing listFilesV2(String bucket, String prefix, String marker, int limit, String delimiter)
199+
throws QiniuException {
200+
Response response = listV2(bucket, prefix, marker, limit, delimiter);
201+
final String result = response.bodyString();
202+
response.close();
203+
List<String> lineList = Arrays.asList(result.split("\n"));
204+
FileListing fileListing = new FileListing();
205+
List<FileInfo> fileInfoList = new ArrayList<>();
206+
Set<String> commonPrefixSet = new HashSet<>();
207+
for (int i = 0; i < lineList.size(); i++) {
208+
String line = lineList.get(i);
209+
JsonObject jsonObject = Json.decode(line, JsonObject.class);
210+
if (!(jsonObject.get("item") instanceof JsonNull))
211+
fileInfoList.add(Json.decode(jsonObject.get("item"), FileInfo.class));
212+
String dir = jsonObject.get("dir").getAsString();
213+
if (!"".equals(dir)) commonPrefixSet.add(dir);
214+
if (i == lineList.size() - 1)
215+
fileListing.marker = jsonObject.get("marker").getAsString();
216+
}
217+
fileListing.items = fileInfoList.toArray(new FileInfo[]{});
218+
fileListing.commonPrefixes = commonPrefixSet.toArray(new String[]{});
219+
220+
return fileListing;
167221
}
168222

223+
169224
/**
170225
* 获取空间中文件的属性
171226
*
@@ -180,7 +235,6 @@ public FileInfo stat(String bucket, String fileKey) throws QiniuException {
180235
return r.jsonToObject(FileInfo.class);
181236
}
182237

183-
184238
/**
185239
* 删除指定空间、文件名的文件
186240
*
@@ -230,7 +284,6 @@ public Response changeHeaders(String bucket, String key, Map<String, String> hea
230284
return rsPost(bucket, path, null);
231285
}
232286

233-
234287
/**
235288
* 修改文件的类型(普通存储或低频存储)
236289
*
@@ -306,7 +359,6 @@ public void copy(String fromBucket, String fromFileKey, String toBucket, String
306359
copy(fromBucket, fromFileKey, toBucket, toFileKey, false);
307360
}
308361

309-
310362
/**
311363
* 移动文件,要求空间在同一账号下
312364
*
@@ -339,7 +391,6 @@ public Response move(String fromBucket, String fromFileKey, String toBucket, Str
339391
return move(fromBucket, fromFileKey, toBucket, toFileKey, false);
340392
}
341393

342-
343394
/**
344395
* 抓取指定地址的文件,以指定名称保存在指定空间
345396
* 要求指定url可访问,大文件不建议使用此接口抓取。可先下载再上传
@@ -381,7 +432,6 @@ public FetchRet fetch(String url, String bucket, String key) throws QiniuExcepti
381432
* @return Response
382433
* @throws QiniuException
383434
*/
384-
385435
public Response asynFetch(String url, String bucket, String key) throws QiniuException {
386436
String requesturl = configuration.apiHost(auth.accessKey, bucket) + "/sisyphus/fetch";
387437
StringMap stringMap = new StringMap().put("url", url).put("bucket", bucket).putNotNull("key", key);
@@ -520,18 +570,15 @@ public BucketInfo getBucketInfo(String bucket) throws QiniuException {
520570
return info;
521571
}
522572

523-
524573
public void setIndexPage(String bucket, IndexPageType type) throws QiniuException {
525574
String url = String.format("%s/noIndexPage?bucket=%s&noIndexPage=%s",
526575
configuration.ucHost(), bucket, type.getType());
527576
Response res = post(url, null);
528577
}
529578

530-
531579
/*
532580
* 相关请求的方法列表
533581
* */
534-
535582
private Response rsPost(String bucket, String path, byte[] body) throws QiniuException {
536583
check(bucket);
537584
String url = configuration.rsHost(auth.accessKey, bucket) + path;
@@ -592,7 +639,6 @@ public BatchOperations() {
592639
/**
593640
* 添加chgm指令
594641
*/
595-
596642
public BatchOperations addChgmOp(String bucket, String key, String newMimeType) {
597643
String resource = encodedEntry(bucket, key);
598644
String encodedMime = UrlSafeBase64.encodeToString(newMimeType);

src/main/java/com/qiniu/util/Json.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
import com.google.gson.Gson;
44
import com.google.gson.GsonBuilder;
5+
import com.google.gson.JsonElement;
56
import com.google.gson.reflect.TypeToken;
67

78
import java.lang.reflect.Type;
89
import java.util.Map;
910

10-
1111
public final class Json {
1212
private Json() {
1313
}
@@ -24,6 +24,11 @@ public static <T> T decode(String json, Class<T> classOfT) {
2424
return new Gson().fromJson(json, classOfT);
2525
}
2626

27+
public static <T> T decode(JsonElement jsonElement, Class<T> clazz) {
28+
Gson gson = new Gson();
29+
return gson.fromJson(jsonElement, clazz);
30+
}
31+
2732
public static StringMap decode(String json) {
2833
// CHECKSTYLE:OFF
2934
Type t = new TypeToken<Map<String, Object>>() {

0 commit comments

Comments
 (0)