繁体   English   中英

AWS S3 上传文件名不匹配

[英]AWS S3 upload file name mismatch

我可以一次将多个文件上传到 s3 存储桶。 但是,文件名与我提供和上传的文件不匹配。 我对文件名感兴趣,因为我需要基于此生成云前端签名的 url。

文件生成代码

final String fileName = System.currentTimeMillis() + pictureData.getFileName();
final File file = new File(fileName); //fileName is -> 1594125913522_image1.png
writeByteArrayToFile(img, file);

AWS 文件上传代码

public void uploadMultipleFiles(final List<File> files) {

        final TransferManager transferManager = TransferManagerBuilder.standard().withS3Client(amazonS3).build();
        try {
            final MultipleFileUpload xfer = transferManager.uploadFileList(bucketName, null, new File("."), files);
            xfer.waitForCompletion();
        } catch (InterruptedException exception) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("InterruptedException occurred=>" + exception);
            }
        } catch (AmazonServiceException exception) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("AmazonServiceException occurred =>" + exception);
            }
            throw exception;
        }
    }

上传的文件名为94125913522_image1.png 如您所见,前两个字符消失了。 我在这里想念什么。 我无法弄清楚。 好心劝告。

private static void writeByteArrayToFile(final byte[] byteArray, final File file) {
        try (OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(Paths.get(file.getName())))) {
            outputStream.write(byteArray);
        } catch (IOException exception) {
            throw new FileIllegalStateException("Error while writing image to file", exception);
        }
    }

问题的原因

由于此方法的第三个参数,您会丢失文件名的前两个字符:

transferManager.uploadFileList(bucketName, null, new File("."), files);

在这种情况下会发生什么

那么,第三个论点是什么:

/**
...
* @param directory
* The common parent directory of files to upload. The keys
* of the files in the list of files are constructed relative to
* this directory and the virtualDirectoryKeyPrefix.
...
*/
public MultipleFileUpload uploadFileList(... , File directory, ...){...}

以及如何使用:

...
int startingPosition = directory.getAbsolutePath().length();
            if (!(directory.getAbsolutePath().endsWith(File.separator)))
                startingPosition++;
...
String key = f.getAbsolutePath().substring(startingPosition)...

因此,目录变量用于定义起始索引以修剪文件路径以获取文件密钥。

当您将new File(".")作为目录传递时,文件的父目录将是{your_path}。

但这是一个目录,您需要处理其中的文件。 因此,从您的目录文件中检索的公共部分是{your_path}./

这比您实际需要的符号多 2 个。 出于这个原因,此方法会修剪 2 个额外字符 - 修剪文件路径时额外移动两个字符。

解决方案

如果只需要处理当前目录,可以通过如下方式传递当前目录:

MultipleFileUpload upload = transferManager.uploadFileList(bucketName, "", 
                            System.getProperty("user.dir"), files);

但是如果你开始使用外部资源,它就行不通了。 因此,您可以使用此代码,它从一个目录中为每组文件创建一个 MultipleFileUpload。


private final String PATH_SEPARATOR = File.separator;
private String bucketName;
private TransferManager transferManager;

public void uploadMultipleFiles(String prefix, List<File> filesToUpload){
    Map<File, List<File>> multipleUploadArguments = 
                  getMultipleUploadArguments(filesToUpload);
    for (Map.Entry<File, List<File>> multipleUploadArgument:
                                      multipleUploadArguments.entrySet()){
        try{
            MultipleFileUpload upload = transferManager.uploadFileList(
                    bucketName, prefix,
                    multipleUploadArgument.getKey(),
                    multipleUploadArgument.getValue()
            );
            upload.waitForCompletion();
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        }
    }
}

private Map<File, List<File>> getMultipleUploadArguments(List<File> filesToUpload){
    return filesToUpload.stream()
            .collect(Collectors.groupingBy(this::getDirectoryPathForFile));
}

private File getDirectoryPathForFile(File file){
    String filePath = file.getAbsolutePath();
    String directoryPath = filePath.substring(0, filePath.lastIndexOf(PATH_SEPARATOR));
    return new File(directoryPath);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM