AWS 使用 JAVA 从 s3 对象创建新文件时出错
AWS Creating new files from an s3 object using JAVA getting error
我有一个形状文件,我需要从我的 java 代码中读取形状文件。我使用下面的代码读取形状文件。
public class App {
public static void main(String[] args) {
File file = new File("C:\Test\sample.shp");
Map<String, Object> map = new HashMap<>();//
try {
map.put("url", URLs.fileToUrl(file));
DataStore dataStore = DataStoreFinder.getDataStore(map);
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource source = dataStore.getFeatureSource(typeName);
SimpleFeatureCollection collection = source.getFeatures();
try (FeatureIterator<SimpleFeature> features = collection.features()) {
while (features.hasNext()) {
SimpleFeature feature = features.next();
SimpleFeatureType schema = feature.getFeatureType();
Class<?> geomType = schema.getGeometryDescriptor().getType().getBinding();
String type = "";
if (Polygon.class.isAssignableFrom(geomType) || MultiPolygon.class.isAssignableFrom(geomType)) {
MultiPolygon geom = (MultiPolygon) feature.getDefaultGeometry();
type = "Polygon";
if (geom.getNumGeometries() > 1) {
type = "MultiPolygon";
}
} else if (LineString.class.isAssignableFrom(geomType)
|| MultiLineString.class.isAssignableFrom(geomType)) {
} else {
}
System.out.println(feature.getDefaultGeometryProperty().getValue().toString());
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
我得到了想要的输出。但我的要求是编写一个 aws lambda 函数来读取形状文件。为了这
1. 我创建了一个 s3 事件的 Lambda java 项目。我在 handleRequest 中编写了相同的代码。我将 java lambda 项目作为 lanbda 函数上传并添加了一个触发器。当我将 .shp 文件上传到 as s3 存储桶时,lmbda 函数将自动调用。但是我收到如下错误
java.lang.RuntimeException: java.io.FileNotFoundException: /sample.shp (No such file or directory)
我的 s3 存储桶中有 sample.shp 文件。我通过下面 link。
How to write an S3 object to a file?
我遇到了同样的错误。我试着像下面这样更改我的代码
S3Object object = s3.getObject(new GetObjectRequest(bucket, key));
InputStream objectData = object.getObjectContent();
map.put("url", objectData );
而不是
File file = new File("C:\Test\sample.shp");
map.put("url", URLs.fileToUrl(file));
:-( 现在我收到如下错误
java.lang.NullPointerException
我也尝试了下面的代码
DataStore dataStore = DataStoreFinder.getDataStore(objectData);
而不是
DataStore dataStore = DataStoreFinder.getDataStore(map);
错误如下
java.lang.ClassCastException:
com.amazonaws.services.s3.model.S3ObjectInputStream cannot be cast to
java.util.Map
我还尝试将键直接添加到地图以及作为 DataStore 对象。一切都出错了..:-(
有没有人可以帮助我?
如果有人可以为我做这将是非常有帮助的...
geotools 中的 DataStoreFinder.getDataStore 方法要求您提供包含 key/value 对和键 "url" 的地图。与该 "url" 键关联的值需要是一个文件 URL,例如 "file://host/path/my.shp".
您正在尝试将 Java 输入流插入到地图中。那行不通,因为它不是文件 URL.
geotools 库不接受 http/https URLs(参见 geotools 代码 here and here),所以你需要一个 file:// URL。这意味着您需要将文件从 S3 下载到本地 Lambda 文件系统,然后提供指向该本地文件的 file:// URL。为此,这里是 Java 应该有效的代码:
// get the shape file from S3 to local filesystem
File localshp = new File("/tmp/download.shp");
s3.getObject(new GetObjectRequest(bucket, key), localshp);
// now store file:// URL in the map
map.put("url", localshp.getURI().getURL().toString());
如果 geotools 库接受了真实的 URLs(不仅仅是 file:// URLs)那么你可以避免下载并简单地创建一个有时间限制的预签名URL 用于 S3 对象并将其 URL 放入地图中。
这是一个如何做到这一点的例子:
// get current time and add one hour
java.util.Date expiration = new java.util.Date();
long msec = expiration.getTime();
msec += 1000 * 60 * 60;
expiration.setTime(msec);
// request pre-signed URL that will allow bearer to GET the object
GeneratePresignedUrlRequest gpur = new GeneratePresignedUrlRequest(bucket, key);
gpur.setMethod(HttpMethod.GET);
gpur.setExpiration(expiration);
// get URL that will expire in one hour
URL url = s3.generatePresignedUrl(gpur);
我有一个形状文件,我需要从我的 java 代码中读取形状文件。我使用下面的代码读取形状文件。
public class App {
public static void main(String[] args) {
File file = new File("C:\Test\sample.shp");
Map<String, Object> map = new HashMap<>();//
try {
map.put("url", URLs.fileToUrl(file));
DataStore dataStore = DataStoreFinder.getDataStore(map);
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureSource source = dataStore.getFeatureSource(typeName);
SimpleFeatureCollection collection = source.getFeatures();
try (FeatureIterator<SimpleFeature> features = collection.features()) {
while (features.hasNext()) {
SimpleFeature feature = features.next();
SimpleFeatureType schema = feature.getFeatureType();
Class<?> geomType = schema.getGeometryDescriptor().getType().getBinding();
String type = "";
if (Polygon.class.isAssignableFrom(geomType) || MultiPolygon.class.isAssignableFrom(geomType)) {
MultiPolygon geom = (MultiPolygon) feature.getDefaultGeometry();
type = "Polygon";
if (geom.getNumGeometries() > 1) {
type = "MultiPolygon";
}
} else if (LineString.class.isAssignableFrom(geomType)
|| MultiLineString.class.isAssignableFrom(geomType)) {
} else {
}
System.out.println(feature.getDefaultGeometryProperty().getValue().toString());
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
我得到了想要的输出。但我的要求是编写一个 aws lambda 函数来读取形状文件。为了这 1. 我创建了一个 s3 事件的 Lambda java 项目。我在 handleRequest 中编写了相同的代码。我将 java lambda 项目作为 lanbda 函数上传并添加了一个触发器。当我将 .shp 文件上传到 as s3 存储桶时,lmbda 函数将自动调用。但是我收到如下错误
java.lang.RuntimeException: java.io.FileNotFoundException: /sample.shp (No such file or directory)
我的 s3 存储桶中有 sample.shp 文件。我通过下面 link。 How to write an S3 object to a file?
我遇到了同样的错误。我试着像下面这样更改我的代码
S3Object object = s3.getObject(new GetObjectRequest(bucket, key));
InputStream objectData = object.getObjectContent();
map.put("url", objectData );
而不是
File file = new File("C:\Test\sample.shp");
map.put("url", URLs.fileToUrl(file));
:-( 现在我收到如下错误
java.lang.NullPointerException
我也尝试了下面的代码
DataStore dataStore = DataStoreFinder.getDataStore(objectData);
而不是
DataStore dataStore = DataStoreFinder.getDataStore(map);
错误如下
java.lang.ClassCastException: com.amazonaws.services.s3.model.S3ObjectInputStream cannot be cast to java.util.Map
我还尝试将键直接添加到地图以及作为 DataStore 对象。一切都出错了..:-(
有没有人可以帮助我? 如果有人可以为我做这将是非常有帮助的...
geotools 中的 DataStoreFinder.getDataStore 方法要求您提供包含 key/value 对和键 "url" 的地图。与该 "url" 键关联的值需要是一个文件 URL,例如 "file://host/path/my.shp".
您正在尝试将 Java 输入流插入到地图中。那行不通,因为它不是文件 URL.
geotools 库不接受 http/https URLs(参见 geotools 代码 here and here),所以你需要一个 file:// URL。这意味着您需要将文件从 S3 下载到本地 Lambda 文件系统,然后提供指向该本地文件的 file:// URL。为此,这里是 Java 应该有效的代码:
// get the shape file from S3 to local filesystem
File localshp = new File("/tmp/download.shp");
s3.getObject(new GetObjectRequest(bucket, key), localshp);
// now store file:// URL in the map
map.put("url", localshp.getURI().getURL().toString());
如果 geotools 库接受了真实的 URLs(不仅仅是 file:// URLs)那么你可以避免下载并简单地创建一个有时间限制的预签名URL 用于 S3 对象并将其 URL 放入地图中。
这是一个如何做到这一点的例子:
// get current time and add one hour
java.util.Date expiration = new java.util.Date();
long msec = expiration.getTime();
msec += 1000 * 60 * 60;
expiration.setTime(msec);
// request pre-signed URL that will allow bearer to GET the object
GeneratePresignedUrlRequest gpur = new GeneratePresignedUrlRequest(bucket, key);
gpur.setMethod(HttpMethod.GET);
gpur.setExpiration(expiration);
// get URL that will expire in one hour
URL url = s3.generatePresignedUrl(gpur);