Skip to content

Commit 737d106

Browse files
authored
Merge pull request #384 from NigelWu95/dev3
update BucketManager to add v2 list function.
2 parents 423c1fd + ced31eb commit 737d106

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

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

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
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.*;
9-
10-
import java.util.ArrayList;
11-
import java.util.Iterator;
12-
import java.util.Map;
11+
import java.util.*;
1312

1413
/**
1514
* 主要涉及了空间资源管理及批量操作接口的实现,具体的接口规格可以参考
@@ -159,8 +158,14 @@ public FileListIterator createFileListIterator(String bucket, String prefix, int
159158
return new FileListIterator(bucket, prefix, limit, delimiter);
160159
}
161160

161+
private String listQuery(String bucket, String prefix, String marker, int limit, String delimiter) {
162+
StringMap map = new StringMap().put("bucket", bucket).putNotEmpty("marker", marker)
163+
.putNotEmpty("prefix", prefix).putNotEmpty("delimiter", delimiter).putWhen("limit", limit, limit > 0);
164+
return map.formString();
165+
}
166+
162167
/**
163-
* 根据前缀获取文件列表
168+
* 列举空间文件 v1 接口,返回一个 response 对象。
164169
*
165170
* @param bucket 空间名
166171
* @param prefix 文件名前缀
@@ -170,16 +175,69 @@ public FileListIterator createFileListIterator(String bucket, String prefix, int
170175
* @return
171176
* @throws QiniuException
172177
*/
178+
public Response listV1(String bucket, String prefix, String marker, int limit, String delimiter)
179+
throws QiniuException {
180+
String url = String.format("%s/list?%s", configuration.rsfHost(auth.accessKey, bucket),
181+
listQuery(bucket, prefix, marker, limit, delimiter));
182+
return get(url);
183+
}
184+
173185
public FileListing listFiles(String bucket, String prefix, String marker, int limit, String delimiter)
174186
throws QiniuException {
175-
StringMap map = new StringMap().put("bucket", bucket).putNotEmpty("marker", marker)
176-
.putNotEmpty("prefix", prefix).putNotEmpty("delimiter", delimiter).putWhen("limit", limit, limit > 0);
187+
Response response = listV1(bucket, prefix, marker, limit, delimiter);
188+
if (!response.isOK()) {
189+
throw new QiniuException(response);
190+
}
191+
FileListing fileListing = response.jsonToObject(FileListing.class);
192+
response.close();
193+
return fileListing;
194+
}
177195

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

240+
183241
/**
184242
* 获取空间中文件的属性
185243
*

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)