Tworzę api, aby wysyłać mi pliki i przesyłam je do S3, a do tego używam biblioteki akka-stream-alpakka-s3, aby to zrobić za pomocą strumieni.

Mój problem polega na tym, że w moim kontrolerze mogę przekonwertować plik na plik Jave:

  def uploadToS3() = Action(parse.multipartFormData) { request =>
    request.body.file("file").map { filePart =>
      val filename = Paths.get(filePart.filename).getFileName
      val file = Paths.get(s"/tmp/$filename").toFile // this is java file
      saveToS3(file, filename)
    }
    ...
  }

A w moim func usługi s3 mogę używać tylko pliku scala, ponieważ ma on funkcję „toByteArray” i potrzebuję go do źródła, wygląda to tak:

import scala.reflect.io.File

class S3Service @Inject()(mys3Client: S3Client,
                          configuration: Configuration,
                          implicit val executionContext: ExecutionContext,
                          implicit val actorSystem: ActorSystem) {

  implicit val materializer: ActorMaterializer = ActorMaterializer()
  val bucket: String = configuration.get[String]("my.aws.s3.bucket")

// func to save to s3
  def saveToS3(file: File, fileName: String): Future[AWSLocation] = {

// here im creating uuid so i to pass as directory so it will be possible to have files with the same name
    val fileNameUUID: String = s"${UUID.randomUUID()}-$fileName"
// this will be my sinc for the stream    
    val s3Sink: Sink[ByteString, Future[MultipartUploadResult]] = mys3Client.multipartUpload(s"$bucket/$fileNameUUID", fileName)

// here is my issue: i need to transform the file to bytstring so I can creat it as the source but the file im getting from the controller is Java file and the function to create byteString is of Scala file so had to use scala file in this func.
    Future.fromTry( Try{
      ByteString(file.toByteArray())
    }).flatMap { byteString =>
      Source.single(byteString).runWith(s3Sink) map { res =>
        AWSLocation(s"$bucket/$fileNameUUID", res.key)
      }
    }.recover {
      case ex: S3Exception =>
        logger.error("some message", ex)
        throw ex
      case ex: Throwable =>
        logger.error("some message", ex)
        throw ex
    }
  }
}

Jaki byłby najlepszy sposób na wyrównanie typów plików, abym mógł przekazać plik bytestring do mojego źródła?

4
jack miao 19 listopad 2018, 16:48

1 odpowiedź

Najlepsza odpowiedź

Spójrz na FileIO.fromPath co da Ci Source[ByteString, ...] od java.nio.file.Path.

2
dvim 19 listopad 2018, 17:23