代码之家  ›  专栏  ›  技术社区  ›  WomenWhoCode

“递归”获取s3子文件夹中的所有文件

  •  -2
  • WomenWhoCode  · 技术社区  · 6 年前

    我需要帮助递归地获取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
    

    我需要获取给定bucket的文件名为的所有文件路径:

    我试过下面的方法,但它对我不起作用(它返回的不是整个路径):

    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 回复  |  直到 6 年前
        1
  •  2
  •   Longarmx    6 年前

    getCommonPrefixes() 只列出 前缀 ,而不是实际的键。从 documentation :

    例如,考虑一个包含以下键的bucket:

    • “foo/bar/baz”
    • “foo/bar/bash”
    • “foo/bar/bang”
    • “嘘声/嘘声”

    如果调用 带有前缀“foo/”和分隔符“/”的列表对象 bucket,返回的s3objectlisting将包含 公共前缀列表(“foo/bar/”)和所有以 该公共前缀将包含在对象摘要列表中。

    相反,使用 getObjectSummaries() 去拿钥匙。你还需要移除 withDelimiters() . 这导致s3只列出当前“目录”中的项。此方法对我有效:

    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 bucket:

    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
  •  4
  •   madhead    6 年前

    有一个新的实用类 S3Objects –这提供了一种在“foreach”语句中迭代amazon s3对象的简单方法。使用它 withPrefix 方法,然后迭代它们。你也可以使用过滤器和流。

    下面是一个示例(kotlin):

    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 ->
                …
            }
        }
    
        3
  •  -1
  •   Jswq    6 年前

    下面是一个关于如何获取目录中所有文件的示例,希望可以帮助您:

      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;
        }