11package com .qiniu .storage ;
22
3+ import com .google .gson .JsonNull ;
4+ import com .google .gson .JsonObject ;
35import com .qiniu .common .Constants ;
46import com .qiniu .common .QiniuException ;
57import com .qiniu .http .Client ;
68import com .qiniu .http .Response ;
79import com .qiniu .storage .model .*;
810import 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 *
0 commit comments