如何在用 Java 编写的 AWS Lambda 函数中读取文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36463310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read a file in AWS Lambda Function written in Java ?
提问by Sumit Arora
I have written an AWS Lambda Handler as below :
我编写了一个 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();
}
}
}
}
Its read a file : City.db , available in resources folder, even I kept to everywhere see below :
它读取了一个文件: City.db ,在资源文件夹中可用,即使我到处都看到如下:
But it showing following message on execution of this lambda function :
但它在执行此 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.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
Contents of the Pom.xml file :
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>
I have used various ways to keep file here and there , but at the end its not working. May you please let me know what is wrong here ?
我使用了各种方法来保存文件,但最终它不起作用。你能告诉我这里有什么问题吗?
However in my another project where I have kept xyz.properties file in resources folder and reading from a PropertyManager file, its working fine. When I tested it on my system its working fine, but on AWS Lambda function it doesn't work.
然而,在我的另一个项目中,我将 xyz.properties 文件保存在资源文件夹中并从 PropertyManager 文件中读取,它工作正常。当我在我的系统上测试它时它工作正常,但在 AWS Lambda 函数上它不起作用。
回答by Sumit Arora
I have made following changes in my code and now its works perfect :
我在我的代码中做了以下更改,现在它的工作完美了:
Majorly changed following two lines :
主要改变了以下两行:
ClassLoader classLoader = getClass().getClassLoader();
ClassLoader classLoader = getClass().getClassLoader();
File cityFile = new File(classLoader.getResource("City.db").getFile());
File cityFile = new File(classLoader.getResource("City.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();
}
}
}
回答by Rito
This is how I did it, let's say this is how your project structure looks like -
我就是这样做的,假设这就是您的项目结构的样子 -
And you want to read the file config.propertieswhich is inside the project-dir/resources directory.
并且您想读取位于project-dir/resources 目录中的文件config.properties。
The code for reading the content of the file would be -
读取文件内容的代码是 -
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
}
If you are following this project structure and using this code, then it will work in AWS Lambda.
如果您遵循此项目结构并使用此代码,那么它将在 AWS Lambda 中工作。
PropertyUtilityis just a utility class that I have created to read the contents of the config file. The PropertyUtility class looks like this -
PropertyUtility只是我创建的一个实用程序类,用于读取配置文件的内容。PropertyUtility 类看起来像这样 -
As you can see in the above code, the path of the config file is different in the local system and in Lambda Instance.
从上面的代码可以看出,配置文件的路径在本地系统和Lambda Instance中是不同的。
In your local machine, PropertyUtility.class.getResource("/")points to bin, that is why you have to do path.getParent(), to point it to the project-directory which is HelloLambdain this example.
在您的本地机器上,PropertyUtility.class.getResource("/")指向bin,这就是为什么您必须执行path.getParent(),将其指向项目目录,在本例中为HelloLambda。
For the Lambda Instance, PropertyUtility.class.getResource("/")points directly to the project-directory.
对于 Lambda 实例,PropertyUtility.class.getResource("/")直接指向项目目录。
回答by Shafiul
If the file in located under resources directory, then the following solution should work:
如果文件位于资源目录下,则以下解决方案应该有效:
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.
}
Here the most important part is "resources/config.json", it must not be "/resources/config.json", because the file location is /var/task/resources/config.json in lambda, I checked.
这里最重要的部分是“resources/config.json”,它不能是“/resources/config.json”,因为文件位置是/var/task/resources/config.json在lambda中,我检查过。
Hope this helps who still face problem in reading file in aws lambda.
希望这有助于在 aws lambda 中读取文件时仍然面临问题的人。
回答by Shivani Pahuja
If the file is located under resources folder, you can use it directly in lambda by using something like the following code:
如果文件位于资源文件夹下,您可以通过使用类似以下代码的内容直接在 lambda 中使用它:
final BufferedReader br = new BufferedReader(new FileReader("/flows/cancellation/MessageArray.json"));
I wanted to read a json file, you can have different use case, but the code works.