Scala 将AWS S3对象转换为ByteString问题

Scala 将AWS S3对象转换为ByteString问题,scala,amazon-s3,akka,Scala,Amazon S3,Akka,我正在使用Akka将文件从S3上传到Facebook。根据FacebookAPI文档,文件应该通过小块上传。根据文件大小,Facebook会给你一个关于字节偏移量的信息,它希望在下一个请求中收到这个信息 首先,我通过Java AWS SDK向S3发出GetObjectRequest,以便接收具有所需字节大小的块: val-objChunkReq=new-GetObjectRequest(get.s3ObjId.bucketName,get.s3ObjId.key) objChunkReq.set

我正在使用Akka将文件从S3上传到Facebook。根据FacebookAPI文档,文件应该通过小块上传。根据文件大小,Facebook会给你一个关于字节偏移量的信息,它希望在下一个请求中收到这个信息

首先,我通过Java AWS SDK向S3发出
GetObjectRequest
,以便接收具有所需字节大小的块:

val-objChunkReq=new-GetObjectRequest(get.s3ObjId.bucketName,get.s3ObjId.key)
objChunkReq.setRange(get.fbUploadSession.from,get.fbUploadSession.to)
尝试(s3Client.getObject(objChunkReq))匹配{
案例成功(s3ObjChunk)=>正确(s3ObjChunk(s3ObjChunk,get.fbUploadSession))
案例失败(ex)=>左侧(S3Exception(ex.getMessage))
}
如果S3响应成功,我可以像处理
InputStream
一样处理接收到的区块,以便将其传递到Facebook HTTP请求:

专用def inputStreamToArrayByte(is:InputStream)={
试一试{
val reads:Int=is.read()
val byteStringBuilder=ByteString.newBuilder
而(is.read()!=-1){
byteStringBuilder.asOutputStream.write(读取)
is.read()
}
is.close()
byteStringBuilder.result()
}
}
我面临的问题是,第一个代码段中的
s3ObjChunk
的字节大小是第二个代码段中的
ByteString
的两倍

s3ObjChunk.getObjectMetadata.getContentLength==n

byteStringBuilder.result().length==n/2

我有两个假设: a) 我错误地将
InputStream
转换为
ByteString
b)
ByteString
压缩
InputStream


如何通过TestRing将S3对象
InputStream
正确地转换为
对象?

结果输出中的
n
vs
n/2
问题可能是由实现中的错误造成的

is.read()
在循环中被调用了两次,它的任何返回都不会写入输出流,但只有第一个返回存储在
val reads

实施应更改为以下内容:

val byteStringBuilder = ByteString.newBuilder
val output = byteStringBuilder.asOutputStream
try {
  var reads: Int = is.read() // note "var" instead of "val"
  while (reads != -1) {
    output.write(reads)
    reads = is.read()
  }
} finally {
  is.close() // should it be here or closed by the caller?
  // also close "output"
}
byteStringBuilder.result()
或者,另一种方法是在
scala.io.Source
中使用更惯用的流读取,例如:

val byteStringBuilder = ByteString.newBuilder
val output = byteStringBuilder.asOutputStream
scala.io.Source.fromInputStream(is).foreach(output.write(_))
byteStringBuilder.result()

你可以看看这是一个额外的库,应该包括:(我最好用原生的Scala或Akka解决方案尝试一下。但是无论如何,谢谢:)使用AWS库已经是一个额外的库,另一方面Benji基于Akka流,所以本质上是被动的,Scala非常感谢关于可能的bug的提示。明天我将尝试你的两个建议,并再次回复评论!