java.io.FileNotFoundException (файловая система только для чтения) // Загрузка файлов в S3

Я пытаюсь создать CSV-файлы из списка карт и загрузить их в корзину S3 с помощью лямбда-функции. Ниже приведен код:

public void createCSV(List<Map<String, AttributeValue>> changedRecords, Context context, String tableName)
            throws IOException {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String outputName = tableName + "_" + formatter.format(calendar.getTime()) + ".csv";

        List<String> headers = changedRecords.stream().flatMap(map -> map.keySet().stream()).distinct()
                .collect(Collectors.toList());

        try (FileWriter writer = new FileWriter(outputName, true);) {
            for (String string : headers) {
                writer.write(string);
                writer.write(",");
            }
            writer.write("\r\n");
            for (Map<String, AttributeValue> lmap : changedRecords) {
                for (Entry<String, AttributeValue> string2 : lmap.entrySet()) {
                    writer.write(string2.getValue().getS());
                    writer.write(",");
                }
                writer.write("\r\n");
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        s3.putObject(new PutObjectRequest("bucket_name", "data/" + outputName, outputName));
    }

Получение следующего исключения fileNotFound:

java.io.FileNotFoundException: data_20200227192207.csv (файловая система только для чтения) в java.io.FileOutputStream.open0 (собственный метод) в java.io.FileOutputStream.open(FileOutputStream.java:270) в java.io.FileOutputStream. (FileOutputStream.java:213) в java.io.FileOutputStream.(FileOutputStream.java:133) в java.io.FileWriter.(FileWriter.java:78) в com.amazonaws.lambda.demo.PLMLambda.createCSV(PLMLambda. java:84) по адресу com.amazonaws.lambda.demo.PLMLambda.handleRequest(PLMLambda.java:54) по адресу com.amazonaws.lambda.demo.PLMLambda.handleRequest(PLMLambda.java:1) по адресу lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest (EventHandlerLoader.java:178) в lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:906) в lambdainternal.AWSLambda.startRuntime(AWSLambda.java:341) в lambdainternal.AWSLambda.(AWSLambda.java:63) в java.lang .Class.forNam e0 (собственный метод) в java.lang.Class.forName(Class.java:348) в lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:114)


person miserable    schedule 27.02.2020    source источник


Ответы (2)


Измените строку:

try (FileWriter writer = new FileWriter(outputName, true);) {

to

try (FileWriter writer = new FileWriter("/tmp" + outputName, true);) {

В Lambda вы можете писать только в каталог /tmp.

person stdunbar    schedule 27.02.2020
comment
Незначительно, но, вероятно, лучше использовать Paths.get("/tmp", outputName), чем конкатенацию строк. - person jarmod; 28.02.2020
comment
Спасибо. Удаляется ли файл автоматически из этого каталога tmp? - person miserable; 28.02.2020
comment
Экземпляр Lambda используется повторно, файл доступен в каталоге tmp. Но AWS не гарантирует этого, поэтому не думайте, что файл всегда доступен для повторного использования. Если экземпляр лямбда был завершен, файл также будет удален. - person Nghia Do; 28.02.2020

Если ваш CSV-контент не такой большой (например, 4 ГБ), вы можете просто использовать StringWriter вместо FileWriter с AWS Lambda, а затем просто поместить строку непосредственно в S3.

person Nghia Do    schedule 28.02.2020