"递归"获取S3中子文件夹中的所有文件

时间:2018-06-15 00:32:09

标签: java amazon-web-services amazon-s3

我需要帮助'递归'抓取s3中的文件:

例如,我有这样的s3结构:

My-bucket/2018/06/05/10/file1.json

My-bucket/2018/06/05/11/file2.json

My-bucket/2018/06/05/12/file3.json

My-bucket/2018/06/05/13/file5.json

My-bucket/2018/06/05/14/file4.json

My-bucket/2018/06/05/15/file6.json

我需要使用给定存储桶的文件名获取所有文件:

我尝试了以下方法,但它对我没有用(它返回的不是整个路径):

public  List<String> getObjectsListFromFolder4(String bucketName, String keyPrefix) {
        List<String> paths = new ArrayList<String>();
        String delimiter = "/";
        if (keyPrefix != null && !keyPrefix.isEmpty() && !keyPrefix.endsWith(delimiter)) {
            keyPrefix += delimiter;
        }

        ListObjectsRequest listObjectRequest = new ListObjectsRequest().withBucketName(bucketName)
                .withPrefix(keyPrefix).withDelimiter(delimiter);

        ObjectListing objectListing;
        do {
            objectListing = s3Client.listObjects(listObjectRequest);
            paths.addAll(objectListing.getCommonPrefixes());
            listObjectRequest.setMarker(objectListing.getNextMarker());
        } while (objectListing.isTruncated());
        return paths;
    }

3 个答案:

答案 0 :(得分:3)

有一个新的实用程序类S3Objects,它提供了一种在“ foreach”语句中迭代Amazon S3对象的简便方法。使用其withPrefix方法,然后对其进行迭代。您也可以使用过滤器和流。

以下是一个示例(科特琳):

val s3 = AmazonS3ClientBuilder
    .standard()
    .withCredentials(EnvironmentVariableCredentialsProvider())
    .build()

S3Objects
    .withPrefix(s3, bucket, folder)
    .filter { s3ObjectSummary ->
        s3ObjectSummary.key.endsWith(".gz")
    }
    .parallelStream()
    .forEach { s3ObjectSummary ->
        CSVParser.parse(
            GZIPInputStream(s3.getObject(s3ObjectSummary.bucketName, s3ObjectSummary.key).objectContent),
            StandardCharsets.UTF_8,
            CSVFormat.DEFAULT
        ).use { csvParser ->
            …
        }
    }

答案 1 :(得分:2)

getCommonPrefixes()仅列出前缀,而不是实际的密钥。来自documentation

  

例如,考虑包含以下键的存储桶:

     
      
  • &#34;富/酒吧/巴兹&#34;
  •   
  • &#34;富/酒吧/ bash的&#34;
  •   
  • &#34;富/酒吧/砰&#34;
  •   
  • &#34;富/嘘声&#34;
  •   
     

如果打电话   listObjects,带有前缀=&#34; foo /&#34;和分隔符=&#34; /&#34;就此而言   在存储桶中,返回的S3ObjectListing将包含一个条目   公共前缀列表(&#34; foo / bar /&#34;)并且没有以#开头的键   该公共前缀将包含在对象摘要列表中。

相反,请使用getObjectSummaries()获取密钥。您还需要删除withDelimiters()。这导致S3仅列出当前&#39;目录中的项目。这种方法对我有用:

public static List<String> getObjectsListFromS3(AmazonS3 s3, String bucket, String prefix) {
    final String delimiter = "/";
    if (!prefix.endsWith(delimiter)) {
        prefix = prefix + delimiter;
    }

    List<String> paths = new LinkedList<>();
    ListObjectsRequest request = new ListObjectsRequest().withBucketName(bucket).withPrefix(prefix);

    ObjectListing result;
    do {
        result = s3.listObjects(request);

        for (S3ObjectSummary summary : result.getObjectSummaries()) {
            // Make sure we are not adding a 'folder'
            if (!summary.getKey().endsWith(delimiter)) {
                paths.add(summary.getKey());
            }
        }
        request.setMarker(result.getMarker());
    }
    while (result.isTruncated());

    return paths;
}

考虑包含以下密钥的S3存储桶:

particle.fs
test/
test/blur.fs
test/blur.vs
test/subtest/particle.fs

使用此驱动程序代码:

public static void main(String[] args) {
    String bucket = "playground-us-east-1-1234567890";
    AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion("us-east-1").build();

    String prefix = "test";
    for (String key : getObjectsListFromS3(s3, bucket, prefix)) {
        System.out.println(key);
    }
}

产生

test/blur.fs
test/blur.vs
test/subtest/particle.fs

答案 2 :(得分:-1)

以下是如何获取目录中所有文件的示例,希望对您有所帮助:

  public static List<String> getAllFile(String directoryPath,boolean isAddDirectory) {
        List<String> list = new ArrayList<String>();
        File baseFile = new File(directoryPath);
        if (baseFile.isFile() || !baseFile.exists()) {
            return list;
        }
        File[] files = baseFile.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                if(isAddDirectory){
                    list.add(file.getAbsolutePath());
                }
                list.addAll(getAllFile(file.getAbsolutePath(),isAddDirectory));
            } else {
                list.add(file.getAbsolutePath());
            }
        }
        return list;
    }