Я работаю над процессом загрузки файлов из S3 в Facebook с помощью Akka. Согласно документации API Facebook, файлы должны загружаться небольшими частями - кусками. В зависимости от размера файла Facebook предоставляет вам информацию о смещении в байтах, которую он ожидает получить в следующем запросе.
Сначала я делаю GetObjectRequest
на S3 через Java AWS SDK, чтобы получить чанк с требуемым размером в байтах:
val objChunkReq = new GetObjectRequest(get.s3ObjId.bucketName, get.s3ObjId.key)
objChunkReq.setRange(get.fbUploadSession.from, get.fbUploadSession.to)
Try(s3Client.getObject(objChunkReq)) match {
case Success(s3ObjChunk) => Right(S3ObjChunk(s3ObjChunk, get.fbUploadSession))
case Failure(ex) => Left(S3Exception(ex.getMessage))
}
Тогда, если ответ S3 успешен, я могу работать с полученным чанком, как с InputStream
, чтобы затем передать его в HTTP-запрос Facebook:
private def inputStreamToArrayByte(is: InputStream) = {
Try {
val reads: Int = is.read()
val byteStringBuilder = ByteString.newBuilder
while (is.read() != -1) {
byteStringBuilder.asOutputStream.write(reads)
is.read()
}
is.close()
byteStringBuilder.result()
}
}
Проблема, с которой я столкнулся, заключается в том, что размер s3ObjChunk
из первого фрагмента кода имеет в два раза больший размер в байтах, чем результирующий ByteString
из второго фрагмента кода.
s3ObjChunk.getObjectMetadata.getContentLength == n
byteStringBuilder.result().length == n / 2
У меня есть два предположения:
а) Я неправильно преобразовываю InputStream
в ByteString
б) ByteString
сжимает InputStream
Как правильно преобразовать объект S3 InputStream
в ByteString
?