我正在将文件保存在S3存储桶中,但是我注意到要执行此操作,我使用FileOutPutStream像这样:

private UploadedFile file; // This is from PrimeFaces, the file that the client wishes to upload
File uploadedFile = new File(file.getFileName()); // Leaving the file like this creates the file on my IDE folder AFTER executing the next two lines, thats why I though the next lines were an error.

FileOutputStream fileOutput = new FileOutputStream(uploadedFile);
fileOutput.write(file.getContents());


因此,这行代码负责在设备上写入文件,尽管这是一个错误或不必要,但我首先要这样做,因为我对将文件上传到亚马逊并不了解,所以我删除了这两行,因为我注意到我的上传方法只需要文件和文件名,如下所示:

businessDelegatorView.uploadPublicRead("mybucketname", fileName, fileToUpload);


所以我虽然这不是必需的,但这只是复制文件:

FileOutputStream fileOutput = new FileOutputStream(uploadedFile);
fileOutput.write(file.getContents());


但是我注意到如果删除它们,上传将不起作用,因为它会抛出一个FileNotFoundException,因此我开始搜索并从BalusC中找到this post,我必须定义一条路径来存储来自客户端的文件将被保存以供以后上载(例如在这种情况下)到亚马逊s3存储桶中,但是我想知道例如在生成.WAR时这样做是否会起作用:

File uplodadFile = new File("C:/xampp/apache/conf", file.getFileName());

FileOutputStream fileOutput = new FileOutputStream(uploadFile);
fileOutput.write(file.getContents());


我将文件保存在那里作为测试,但是我不确定是否不确定FileOutPutStream是正确的选择,我不知道另一种方法。

这也是上面的代码执行后,上传方法的样子,如果没有FileOutPutStream,它将无法正常工作,原因是文件不在我的设备中

AmazonS3 amazonS3 = buildAmazonS3();
         try {
             amazonS3.putObject(new PutObjectRequest(bucketName, key, file).withCannedAcl(CannedAccessControlList.PublicRead));


只是希望有人为我多做一些事情,例如在这里穿上最好的方法是什么?

File uplodadFile = new File("C:/xampp/apache/conf", file.getFileName());


还是真的没关系,我只需要记住.WAR将部署在哪台计算机上?谢谢

最佳答案

只是想让别人为我多清理一些东西,例如
  穿上这里的最佳途径是什么?


如果要将文件上载到系统中,则应将其尽可能长地保留为字节流,因为在输入时会收到字节,并且希望在末尾存储这些相同的字节。转换bytes->file->bytes是费时,资源消耗和容易出错的(编码转换和存储在文件系统上的文件的确可能是错误的来源)。


  所以我虽然这不是必需的,但这只是复制了
  文件:
  
  FileOutputStream fileOutput = new FileOutputStream(uploadedFile); fileOutput.write(file.getContents());


您说对了,因为该文件已经由客户端HTTP请求上传了。
这样做两次看起来很无助。
但是,那里没有File,而是UploadedFile (primefaces)

S3 API的PutObjectRequest()构造函数有多个重载。
实际上,您使用它:

public PutObjectRequest(String bucketName,
                        String key,
                        File file)


最后一个参数是File。您看到不匹配了吗?
在使您烦恼的第一个代码中,您通过writing the content of the File into a new UploadedFile解决了问题(在将UploadedFile作为源时传递File),如果您需要File,则可以接受。
但是实际上,您不需要File,因为PutObjectRequest()构造函数还有另一个overload与您的用法更匹配:

public PutObjectRequest(String bucketName,
                        String key,
                        InputStream input,
                        ObjectMetadata metadata)



  构造一个新的PutObjectRequest对象,以将数据流上传到
  指定的存储桶和密钥。构造请求后,用户
  可以选择指定对象元数据或罐头ACL。


请注意,为了不影响性能,提供内容长度很重要:


  数据流的内容长度必须在对象中指定
  元数据参数; Amazon S3要求先将其传入数据
  已上传。不指定内容长度将导致整个
  输入流的内容要在内存中本地缓冲,以便
  内容长度可以计算出来,这可能导致负数
  性能问题。


所以你可以这样做:

UploadedFile file = ...; // uploaded by client
ObjectMetadata metaData = new ObjectMetadata();
metaData.setContentLength(file.getSize());
amazonS3.putObject(new PutObjectRequest(bucketName, key, file.getInputStream(), metaData)
        .withCannedAcl(CannedAccessControlList.PublicRead));

关于java - 关于文件上传S3的困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57130822/

10-12 00:37
查看更多