Отправка файла, который доступен как входной поток, а не файл

В устаревшей программе, которую я обновляю, в какой-то момент я получаю файл, загруженный пользователем, этот файл необходимо проанализировать во внешней службе.

Я знаю, как отправить файл в сервис, используя спрей. В частности, я знаю, как взять файл с диска, так как спрей API разработан как таковой

В моей текущей конкретной ситуации у меня есть только входной поток, а не файл. Это файл, который загружается пользователем для проведения анализа. То есть, как только у меня будет файл, я отправлю его во внешнюю службу для анализа. Однако API спрей, особенно данные http, работает только с файлом, а не с входным потоком, который является типом данных, в котором у меня есть данные после загрузки файла. Я имею дело с устаревшим кодом.

Мне было интересно, как бороться с тем фактом, что мой файл на данный момент является входным потоком. Я где-то заметил, что решение может записать во временный файл на диске и выполнить загрузку с ним. Но доступ к диску все время звучит для меня долго.

Есть ли другой путь?

Ниже вы можете найти типичный код, который я написал бы по этому вопросу. Однако в этом случае файл доступен только для меня в виде входного потока.

Edit1

import context.dispatcher // execution context for futures below

      val file     = new File((getClass.getResource("/Health-Benefit-Plans.pdf")).toURI)

      val pipeline = addCredentials(BasicHttpCredentials("xxxxx", "xxxxxx")) ~> sendReceive

      val payload  = MultipartFormData(Seq(BodyPart(file, "file", MediaTypes.`application/pdf`)))

      val request  = Post("xxxx/categorization?projectId=xxxxx&language=en", payload)
      pipeline(request)

Edit2:

Вот код BodyPart

    object BodyPart {
  @deprecated("Use a BodyPart.apply overload instead", "1.0/1.1/1.2")
  def forFile(fieldName: String, file: FormFile): BodyPart =
    apply(file, fieldName)

  def apply(file: File, fieldName: String): BodyPart = apply(file, fieldName, ContentTypes.`application/octet-stream`)
  def apply(file: File, fieldName: String, contentType: ContentType): BodyPart =
    apply(HttpEntity(contentType, HttpData(file)), fieldName, Map.empty.updated("filename", file.getName))

  def apply(formFile: FormFile, fieldName: String): BodyPart =
    formFile.name match {
      case Some(name) ⇒ apply(formFile.entity, fieldName, Map.empty.updated("filename", name))
      case None       ⇒ apply(formFile.entity, fieldName)
    }

  def apply(entity: HttpEntity, fieldName: String): BodyPart = apply(entity, fieldName, Map.empty[String, String])
  def apply(entity: HttpEntity, fieldName: String, parameters: Map[String, String]): BodyPart =
    BodyPart(entity, Seq(`Content-Disposition`("form-data", parameters.updated("name", fieldName))))
}

Как видите, нечего иметь дело с входным потоком или чем-то подобным.

1 ответ

Вы можете записать входной поток в байтовый массив в памяти, если вы уверены, что это не вызовет проблем для вашего варианта использования (например,>2 ГБ файлов). Но, честно говоря, вы должны иметь возможность загружать входной поток (при условии, что вы знаете длину) - с какой проблемой вы сталкиваетесь, когда пытаетесь использовать Spray для загрузки?

Другие вопросы по тегам