¿Cómo puedo leer un archivo AWS S3 con Java?

4 minutos de lectura

avatar de usuario
edamame

Intenté leer un archivo de AWS S3 en mi código Java:

  File file = new File("s3n://mybucket/myfile.txt");
  FileInputStream fileInput = new FileInputStream(file);

Entonces recibí un error:

java.io.FileNotFoundException: s3n:/mybucket/myfile.txt (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:146)

¿Hay alguna forma de abrir/leer un archivo de AWS S3? ¡Muchas gracias!

La clase ‘Archivo’ de Java no entiende que S3 existe. Aquí hay un ejemplo de lectura de un archivo de la documentación de AWS:

AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());        
S3Object object = s3Client.getObject(new GetObjectRequest(bucketName, key));
InputStream objectData = object.getObjectContent();
// Process the objectData stream.
objectData.close();

  • ¡Gracias! ¿Hay un jar correspondiente (para esas clases) en maven que pueda usar?

    – Edamame

    17 de febrero de 2015 a las 19:54

  • sí el aws java sdk. también hay Instrucciones de instalación.

    – henificador42

    17 de febrero de 2015 a las 20:02

  • @tedder42, ¿hay alguna API para procesar los datos si el contenido del objeto es un correo electrónico? Quiero obtener el contenido del correo electrónico, de, a, etc.

    usuario4458270

    3 de abril de 2017 a las 11:17


  • @edwiser haga una nueva pregunta y vincúlela aquí; necesita más información.

    – henificador42

    03/04/2017 a las 19:55

  • Parece que está en desuso, use AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build()

    – binario

    7 de marzo de 2018 a las 18:44


avatar de usuario
Enigo

En 2019, hay una forma un poco más óptima de leer un archivo de S3:

private final AmazonS3 amazonS3Client = AmazonS3ClientBuilder.standard().build();

private Collection<String> loadFileFromS3() {
    try (final S3Object s3Object = amazonS3Client.getObject(BUCKET_NAME,
                                                            FILE_NAME);
        final InputStreamReader streamReader = new InputStreamReader(s3Object.getObjectContent(), StandardCharsets.UTF_8);
        final BufferedReader reader = new BufferedReader(streamReader)) {
        return reader.lines().collect(Collectors.toSet());
    } catch (final IOException e) {
        log.error(e.getMessage(), e)
        return Collections.emptySet();
    }
}

  • Óptimo de qué manera (bueno para aclarar)?. Esto termina metiendo todo en la memoria y no usa la semántica de transmisión (bien si tiene archivos pequeños, mal si tiene un archivo de 100 GB).

    – Programador pragmático

    23 de abril de 2020 a las 18:34


Los pasos para leer el archivo S3 en Java pueden ser:

  1. Crear AmazonS3Client.
  2. Cree S3Object usando el nombre y la clave del depósito.
  3. Cree un lector de búfer usando S3Object y lea el archivo línea por línea.

1 >>>

    BasicAWSCredentials awsCreds = new BasicAWSCredentials("accessKey", "secretKey");
    AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
            .withRegion("region_name_here").build();  

2 >>>

   S3Object object = s3Client.getObject(new GetObjectRequest("bucketName", "key"));

3 >>>

   BufferedReader reader = new BufferedReader(new InputStreamReader(object.getObjectContent()));

    String s = null;
    while ((s = reader.readLine()) != null)
    {
        System.out.println(s);
        //your business logic here
    }

Gracias.

También podemos usar software.amazon.awssdk:s3

 //Assuming the credentials are read from Environment Variables, so no hardcoding here

    S3Client client = S3Client.builder()
                        .region(regionSelected)
                        .build();
    
    GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                    .bucket(bucketName)
                    .key(fileName)
                    .build();
    
    ResponseInputStream<GetObjectResponse> responseInputStream = client.getObject(getObjectRequest);

    InputStream stream = new ByteArrayInputStream(responseInputStream.readAllBytes());
    
    
    System.out.println("Content :"+ new String(responseInputStream.readAllBytes(), StandardCharsets.UTF_8));

avatar de usuario
Jorge V. Reilly

Si el contenido del archivo es una cadena, puede usar getObjectAsString. De lo contrario, puede utilizar IOUtils.toByteArray en getObjectContent() para leer el contenido del archivo en una matriz de bytes.

Obviamente, estos se utilizan mejor en objetos S3 pequeños que caben fácilmente en la memoria.

private final AmazonS3 amazonS3Client = AmazonS3ClientBuilder.standard().build();

private String loadStringFromS3() {
    try {
        return amazonS3Client.getObjectAsString(BUCKET_NAME, FILE_NAME);
    } catch (final IOException e) {
        log.error(e.getMessage(), e)
        return null;
    }
}

private byte[] loadDataFromS3() {
    try (final S3Object s3Object = amazonS3Client.getObject(BUCKET_NAME, FILE_NAME)) {
        return IOUtils.toByteArray(s3Object.getObjectContent());
    } catch (final IOException e) {
        log.error(e.getMessage(), e)
        return null;
    } finally {
        IOUtils.closeQuietly(object, log);
    }
}

Esta es mi solución. estoy usando spring boot 2.4.3

Crear un cliente amazon s3

AmazonS3 amazonS3Client = AmazonS3ClientBuilder
                .standard()
                .withRegion("your-region")
                .withCredentials(
                        new AWSStaticCredentialsProvider(
                            new BasicAWSCredentials("your-access-key", "your-secret-access-key")))
                .build();

Crear un cliente de transferencia de amazon.

TransferManager transferManagerClient = TransferManagerBuilder.standard()
                .withS3Client(amazonS3Client)
                .build();

Crear un archivo temporal en /tmp/{tu-clave-s3} para que podamos poner el archivo que descargamos en este archivo.

File file = new File(System.getProperty("java.io.tmpdir"), "your-s3-key"); 

try {
    file.createNewFile(); // Create temporary file
} catch (IOException e) {
    e.printStackTrace();
}

file.mkdirs();  // Create the directory of the temporary file

Luego, descargamos el archivo desde s3 usando cliente del administrador de transferencias

// Note that in this line the s3 file downloaded has been transferred in to the temporary file that we created
Download download = transferManagerClient.download(
               new GetObjectRequest("your-s3-bucket-name", "your-s3-key"), file); 

// This line blocks the thread until the download is finished
download.waitForCompletion();  

Ahora que el archivo s3 se ha transferido con éxito al archivo temporal que creamos. Podemos obtener el InputStream del archivo temporal.

InputStream input = new DataInputStream(new FileInputStream(file));

Porque el archivo temporal ya no es necesario, simplemente lo eliminamos.

file.delete();

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad