为什么要先通过写入磁盘将文件上传到AWS?

时间:2017-11-16 15:54:32

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

此示例使用的文件很可能不在RAM中:

http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjSingleOpJava.html

但是我已经从某个客户端请求获得了一个缓冲文件,在下面的代码中,这个文件被写入磁盘,但是为什么?它通过写入磁盘使整个过程变慢,我不能避免它

编辑(以下是对我要实现的目标的解释):

上传用户的图像,然后由服务器进行缩放,然后保存在服务器的磁盘上,然后将此缩放的图像发送到AWS,然后用户获取图像位于亚马逊服务器上的aws链接。

public void transferToS3(String region, String bucket, String entity, String resolution, String filename, BufferedImage bufferedImage) {
    if (bufferedImage != null) {
        String objectpath = "/" + "images" + "/" + entity + "/" + resolution + "/" + filename + "." + "png";

        Path tmpFile = null;
        try {
            tmpFile = Files.createTempFile(imagesPath, "tmp_", ".png");
        } catch (IOException e) {
            e.printStackTrace();
        }
        tmpFile.toFile().deleteOnExit();

        try {
            ImageIO.write(bufferedImage, "png", tmpFile.toFile());
            S3AsyncClient client = S3AsyncClient.builder().region(Region.of(region)).build();
            CompletableFuture<PutObjectResponse> future = 
                    client.putObject(PutObjectRequest.builder()
                    .bucket(bucket)
                    .key(objectpath)
                    .contentType("image/png")
                    .build(),
                    AsyncRequestProvider.fromFile(tmpFile.toAbsolutePath()));

            Path finalTmpFile = tmpFile;
            future.whenComplete((resp, err) -> {
                try {
                    if (resp != null) {
                        logger.debug(resp.toString());
                    } else {
                        logger.error(err.toString());
                    }
                    Files.deleteIfExists(finalTmpFile.toAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    FunctionalUtils.invokeSafely(client::close);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Scaling例程返回一个缩放的BufferedImage,然后在transferToS3方法中使用。

public BufferedImage scale(int width, int height, BufferedImage bufferedImage) {
    BufferedImage scaledBufferedImage = null;
    if (bufferedImage != null) {
        Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        scaledBufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        scaledBufferedImage.getGraphics().drawImage(image, 0, 0, null);
    }
    return scaledBufferedImage;
} 

上面的两个一起:

BufferedImage scaledBufferedImage = imageService.scale(width, height finalBufferedImage);
imageService.transferToS3(region, bucket, name, k, file, scaledBufferedImage);

1 个答案:

答案 0 :(得分:3)

您可以使用请求中的数据流执行任何操作。您可以随意缩放内存中的图像并将其发送回响应中。您链接的示例将文件写入磁盘,因为这是目前最常见的情况。它还允许作者专注于上传文件的细节,而不会用不相关的代码污染示例。

请注意,bufferedImage 不是文件。这是一个流。我怀疑作者将图像保存到磁盘,以避免假设图像的大小。如果图像太大而无法放入RAM中,那么在内存中进行缩放时会遇到困难。