2016-05-25 57 views
13

Akka HTTP kullanarak uygulamamda dosya yükleme işlevselliği uygulamaya çalışıyorum. akka-stream sürüm 2.4.4 kullanıyorum. İşte Akka HTTP kullanarak dosya yükleme

Bu kod iyi çalışıyor ve verilen yoluna dosya yüklerken ( akka-doc değiştirilmiş) kodu

path("fileupload") { 
    post { 
     extractRequestContext { 
     ctx => { 
      implicit val materializer = ctx.materializer 
      implicit val ec = ctx.executionContext 
      fileUpload("fileUpload") { 
      case (metadata, byteSource) => 
       val location = FileUtil.getUploadPath(metadata) 
       val updatedFileName = metadata.fileName.replaceAll(" ", "").replaceAll("\"", "") 
       val uniqFileName = uniqueFileId.concat(updatedFileName) 
       val fullPath = location + File.separator + uniqFileName 
       val writer = new FileOutputStream(fullPath) 
       val bufferedWriter = new BufferedOutputStream(writer) 

       val result = byteSource.map(s => { 
       bufferedWriter.write(s.toArray) 
       }).runWith(Sink.ignore) 

       val result1 = byteSource.runWith(Sink.foreach(s=>bufferedWriter.write(s.toArray))) 
       Await.result(result1, 5.seconds) 
       bufferedWriter.flush() 
       bufferedWriter.close() 
       complete(uniqFileName) 
      /*onSuccess(result) { x => 
       bufferedWriter.flush() 
       bufferedWriter.close() 
       complete("hello world") 
      }*/ 
      } 
     } 
     } 
    } 
    } 

olduğunu. Dosya adlarının benzersiz olduğundan emin olmak için UUID ekleyerek yeni dosya adları oluşturuyorum. Bu yüzden yeni dosya adını arayan kişiye geri vermem gerekiyor. Ancak, bu yöntem her zaman dosya adını döndürmüyor. Bazen, Response has no content ile bitiriyor.

Burada yanlış yaptığım şeyi bana bilen biri var mı? Bu kod /tmp dizinde içinde bir dosyaya fileUpload çok parçalı alanını yükleyecek

path("fileUpload") { 
    post { 
     fileUpload("fileUpload") { 
     case (fileInfo, fileStream) => 
      val sink = FileIO.toPath(Paths.get("/tmp") resolve fileInfo.fileName) 
      val writeResult = fileStream.runWith(sink) 
      onSuccess(writeResult) { result => 
      result.status match { 
       case Success(_) => complete(s"Successfully written ${result.count} bytes") 
       case Failure(e) => throw e 
      } 
      } 
     } 
    } 
    } 

: Eğer bu amaçla reaktif akışları olduğunda standart engelleme kullanmaya gerek yoktur

+1

Bu, sorunuzun bir cevabı değil, http://doc.akka.io/docs/akka/2.4.6/scala/stream/stages-overview.html#file-io-sinks-and sayfasına bakın. el ile bir dosyaya yazma yerine kaynaklar. Ayrıca, bir rota içinde Await.result kullanarak gerçekten kötü bir stil. –

+0

Şuna bakacağız. Ben Await yerine on ile denedim, aynı büstü. Ben de Await ile çalıştım. Cevabınız için teşekkürler, bağlantıyı deneyeyim. –

+0

@ RüdigerKlaehn FileIO ile denedim, hala aynı sorun var :( –

cevap

14

akışları. Sadece giriş kaynağının içeriğini ilgili dosya havuzuna döker ve yazım işleminin tamamlanması üzerine bir mesaj verir.

their scaladocs'da açıklandığı gibi FileIO kaynakları ve girişleri için kullanılan dağıtıcıyı da değiştirmek isteyebilirsiniz.

+0

Bununla birlikte, bazen yanıtı alamıyorum :(' Yanıt boştu '. Tek fark şu ki, yerine 2.4.4 kullanıyorum 2.4.6 –

+0

Nasıl test edersiniz? Curl? Çok büyük bir dosya mı? –

+0

Chome Extension, Advanced Rest istemcisini kullanarak test yapıyorum Dosya çok büyük değil.Txt, sql, jpeg, png dosyaları ile deneniyor min 2kb için max 2 mb –