使用JavaSDK将多个文件批处理到AmazonS3
我试图通过附加文件,在同一个密钥下将多个文件上传到AmazonS3。我有一个文件名列表,并希望按照该顺序上载/附加文件。我几乎完全遵循,但我循环通过每个文件首先和上传的一部分。因为文件在hdfs上(路径实际上是org.apache.hadoop.fs.Path),所以我使用输入流发送文件数据。下面是一些伪代码(我在逐字逐句地评论教程中的代码块):使用JavaSDK将多个文件批处理到AmazonS3,java,amazon-web-services,hadoop,amazon-s3,aws-java-sdk,Java,Amazon Web Services,Hadoop,Amazon S3,Aws Java Sdk,我试图通过附加文件,在同一个密钥下将多个文件上传到AmazonS3。我有一个文件名列表,并希望按照该顺序上载/附加文件。我几乎完全遵循,但我循环通过每个文件首先和上传的一部分。因为文件在hdfs上(路径实际上是org.apache.hadoop.fs.Path),所以我使用输入流发送文件数据。下面是一些伪代码(我在逐字逐句地评论教程中的代码块): 如果有人知道这一错误的原因,我们将不胜感激。或者,如果有更好的方法将一组文件连接到一个s3密钥中,那也会很好。我试着使用java的内置语言,但没有成功
如果有人知道这一错误的原因,我们将不胜感激。或者,如果有更好的方法将一组文件连接到一个s3密钥中,那也会很好。我试着使用java的内置语言,但没有成功。任何帮助都将不胜感激。作为参考,所有文件的总大小可能高达10-15GB。我知道可能有点晚了,但值得我贡献一点。 我已经使用
SequenceInputStream
解决了类似的问题
诀窍在于能够计算结果文件的总大小,然后向SequenceInputStream
提供枚举
下面是一些可能有帮助的示例代码:
public void combineFiles() {
List<String> files = getFiles();
long totalFileSize = files.stream()
.map(this::getContentLength)
.reduce(0L, (f, s) -> f + s);
try {
try (InputStream partialFile = new SequenceInputStream(getInputStreamEnumeration(files))) {
ObjectMetadata resultFileMetadata = new ObjectMetadata();
resultFileMetadata.setContentLength(totalFileSize);
s3Client.putObject("bucketName", "resultFilePath", partialFile, resultFileMetadata);
}
} catch (IOException e) {
LOG.error("An error occurred while combining files. {}", e);
}
}
private Enumeration<? extends InputStream> getInputStreamEnumeration(List<String> files) {
return new Enumeration<InputStream>() {
private Iterator<String> fileNamesIterator = files.iterator();
@Override
public boolean hasMoreElements() {
return fileNamesIterator.hasNext();
}
@Override
public InputStream nextElement() {
try {
return new FileInputStream(Paths.get(fileNamesIterator.next()).toFile());
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
};
}
public void组合文件(){
List files=getFiles();
long totalFileSize=files.stream()
.map(此::getContentLength)
.减少(0升,(f,s)->f+s);
试一试{
try(InputStream partialFile=newsequenceinputstream(getInputStreamEnumeration(files))){
ObjectMetadata resultFileMetadata=新的ObjectMetadata();
resultFileMetadata.setContentLength(totalFileSize);
s3Client.putObject(“bucketName”、“resultFilePath”、partialFile、resultFileMetadata);
}
}捕获(IOE异常){
LOG.error(“合并文件时出错。{}”,e);
}
}
私有枚举
public void combineFiles() {
List<String> files = getFiles();
long totalFileSize = files.stream()
.map(this::getContentLength)
.reduce(0L, (f, s) -> f + s);
try {
try (InputStream partialFile = new SequenceInputStream(getInputStreamEnumeration(files))) {
ObjectMetadata resultFileMetadata = new ObjectMetadata();
resultFileMetadata.setContentLength(totalFileSize);
s3Client.putObject("bucketName", "resultFilePath", partialFile, resultFileMetadata);
}
} catch (IOException e) {
LOG.error("An error occurred while combining files. {}", e);
}
}
private Enumeration<? extends InputStream> getInputStreamEnumeration(List<String> files) {
return new Enumeration<InputStream>() {
private Iterator<String> fileNamesIterator = files.iterator();
@Override
public boolean hasMoreElements() {
return fileNamesIterator.hasNext();
}
@Override
public InputStream nextElement() {
try {
return new FileInputStream(Paths.get(fileNamesIterator.next()).toFile());
} catch (FileNotFoundException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
};
}