如何在用Java编写的AWS Lambda函数中读取文件?

smtd7mpg  于 2023-02-11  发布在  Java
关注(0)|答案(5)|浏览(147)

我编写了一个AWS Lambda处理程序,如下所示:

package com.lambda;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import java.io.*;

public class TestDetailsHandler implements RequestStreamHandler {

    public void  handleRequest(InputStream input,OutputStream output,Context context){

        // Get Lambda Logger
        LambdaLogger logger = context.getLogger();

        // Receive the input from Inputstream throw exception if any

        File starting = new File(System.getProperty("user.dir"));
            System.out.println("Source Location" + starting);

           File cityFile = new File(starting + "City.db");
        FileInputStream fis = null;

        try {
            fis = new FileInputStream(cityFile);

            System.out.println("Total file size to read (in bytes) : "
                    + fis.available());

            int content;
            while ((content = fis.read()) != -1) {
                // convert to char and display it
                System.out.print((char) content);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}

其读取文件:City.db,可在资源文件夹中,甚至我一直到处看到下面:

但在执行此lambda函数时显示以下消息:

START RequestId: 5216ea47-fc43-11e5-96d5-83c1dcdad75d Version: $LATEST
Source Location/
java.io.FileNotFoundException: /city.db (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at com.lambda.TestDetailsHandler.handleRequest(TestDetailsHandler.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at lambdainternal.EventHandlerLoader$StreamMethodRequestHandler.handleRequest(EventHandlerLoader.java:511)
    at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:972)
    at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:231)
    at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:59)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:93)
END RequestId: 5216ea47-fc43-11e5-96d5-83c1dcdad75d
REPORT RequestId: 5216ea47-fc43-11e5-96d5-83c1dcdad75d  Duration: 58.02 ms  Billed Duration: 100 ms     Memory Size: 1024 MB    Max Memory Used: 50 MB

Pom.xml文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lambda</groupId>
    <artifactId>testdetails</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>test-handler</name>

    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>


        </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我已经用了各种方法来保存文件在这里和那里,但在结束时它不工作。你能让我知道这里出了什么问题吗?
然而,在我的另一个项目中,我把xyz.properties文件保存在resources文件夹中,并从PropertyManager文件中阅读,它工作正常。当我在我的系统上测试它时,它工作正常,但在AWS Lambda函数上它不工作。

aij0ehis

aij0ehis1#

我在我的代码中做了以下更改,现在它的工作完美:
主要变更如下两行:
类加载器= getClass(). getClassLoader();**

    • 文件城市文件=新文件(类加载器. getResource("城市. db"). getFile());**
package com.lambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import java.io.*;

public class TestDetailsHandler implements RequestStreamHandler {

    public void  handleRequest(InputStream input,OutputStream output,Context context){

        // Get Lambda Logger
        LambdaLogger logger = context.getLogger();

        // Receive the input from Inputstream throw exception if any

        ClassLoader classLoader = getClass().getClassLoader();

        File cityFile = new File(classLoader.getResource("City.db").getFile());
        FileInputStream fis = null;

        try {
            fis = new FileInputStream(cityFile);

            System.out.println("Total file size to read (in bytes) : "
                    + fis.available());

            int content;
            while ((content = fis.read()) != -1) {
                // convert to char and display it
                System.out.print((char) content);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

thtygnil

thtygnil2#

我是这么做的,假设你的项目结构是这样的-

您希望读取文件config.properties,该文件位于project-dir/resources目录中。
阅读文件内容的代码是-

InputStream input = null;
try {
    Path path = Paths.get(PropertyUtility.class.getResource("/").toURI());

    // The path for config file in Lambda Instance -
    String resourceLoc = path + "/resources/config.properties";

    input = new FileInputStream(resourceLoc);
} catch(Exception e) {
    // Do whatever
}

如果您遵循此项目结构并使用此代码,那么它将在AWS Lambda中工作。

PropertyUtility只是我创建的一个实用程序类,用于读取配置文件的内容。PropertyUtility类如下所示-

正如您在上面的代码中所看到的,配置文件的路径在本地系统和Lambda示例中是不同的。
在你的本地机器中,PropertyUtility.class.getResource(“/”)指向bin,这就是为什么你必须执行path.getParent(),把它指向项目目录,在这个例子中是HelloLambda
对于Lambda示例,**PropertyUtility.class.getResource(“/”)**直接指向项目目录。

qv7cva1a

qv7cva1a3#

如果文件位于resources目录下,则以下解决方案应起作用:

String fileName = "resources/config.json";

Path path = Paths.get(this.getClass().getResource("/").toURI());
Path resourceLocation = path.resolve(fileName);

try(InputStream configStream = Files.newInputStream(resourceLocation)) {
            //use your file stream as you need.
}

这里最重要的部分是**“resources/config.json”,它一定不能是“/resources/config.json”**,因为我检查了一下,文件的位置是lambda中的/var/task/resources/config. json。
希望这能帮助那些在aws lambda中阅读文件时仍然面临问题的人。

mrphzbgm

mrphzbgm4#

如果该文件位于resources文件夹下,您可以使用类似下面的代码直接在lambda中使用它:

final BufferedReader br = new BufferedReader(new FileReader("/flows/cancellation/MessageArray.json"));

我想读一个json文件,你可以有不同的用例,但代码工作。

olhwl3o2

olhwl3o25#

理想情况下,应该尽可能多地从S3中读取Read以进行动态读取。另外,读取速度非常快。
但是,就像Java代码是基于Maven的一样,根类路径位置从src/main/resources位置开始。
因此,您可以像在任何Web/核心应用程序中一样,从如下所示的类路径中读取-

ClassLoader classLoader = YourClass.class.getClassLoader();
    File cityFile = new 
    File(classLoader.getResource("yourFile").getFile());

这对我很有效!

相关问题