Отправка файла, который доступен как входной поток, а не файл
В устаревшей программе, которую я обновляю, в какой-то момент я получаю файл, загруженный пользователем, этот файл необходимо проанализировать во внешней службе.
Я знаю, как отправить файл в сервис, используя спрей. В частности, я знаю, как взять файл с диска, так как спрей 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 для загрузки?