无法使用 Scala 和 JS 将文件上传到本地主机

Cannot upload file to localhost with Scala and JS

我正在尝试 运行 一个在本地主机 (9000) 上使用 sbt 的开源工具。但是,当我尝试将文件 (.arrf) 上传到该工具时(这是该工具首先需要的),我收到如下图所示的 FileNotFound 错误。

我没有使用 Scala 的经验并且使用 JS 的经验有限,但据我所知,将文件上传到服务器时出现问题。我尝试了不同大小的文件和原作者使用的文件。我查看了代码,文件上传由 FileUploadService.scala class 处理,如下所示,

class FileUploadService(serviceSavePath: String) {

  val basePath = if (serviceSavePath.endsWith("/")) {
    serviceSavePath
  } else { serviceSavePath + "/" }

  val uploadedParts: ConcurrentMap[String, Set[FileUploadInfo]] = new ConcurrentHashMap(8, 0.9f, 1)

  def fileNameFor(fileInfo: FileUploadInfo) = {
    s"${basePath}${fileInfo.resumableIdentifier}-${fileInfo.resumableFilename}"
  }

  def isLast(fileInfo: FileUploadInfo): Boolean = {
    (fileInfo.resumableTotalSize - (fileInfo.resumableChunkSize * fileInfo.resumableChunkNumber)) < fileInfo.resumableChunkSize
  }

  def savePartialFile(filePart: Array[Byte], fileInfo: FileUploadInfo) {
    if (filePart.length != fileInfo.resumableChunkSize & !isLast(fileInfo)) {
      println("error uploading part")
      return
    }
    val partialFile = new RandomAccessFile(fileNameFor(fileInfo), "rw")
    val offset = (fileInfo.resumableChunkNumber - 1) * fileInfo.resumableChunkSize

    try {
      partialFile.seek(offset)
      partialFile.write(filePart, 0, filePart.length)
    } finally {
      partialFile.close()
    }

    val key = fileNameFor(fileInfo)
    if (uploadedParts.containsKey(key)) {
      val partsUploaded = uploadedParts.get(key)
      uploadedParts.put(key, partsUploaded + fileInfo)
    } else {
      uploadedParts.put(key, Set(fileInfo))
    }
  }

据我从错误中了解到,错误发生在 savePartialFile 函数中,它试图创建一个新的随机访问文件。以下是错误发生前最后一次 GET 请求的详细信息。我还在下面添加了错误日志。我添加了很多输出和细节,因为我在 scala 和 web 开发方面经验不足,但我希望一切都清楚。

干杯!

2022-01-05 13:56:15,972 [ERROR] from application in application-akka.actor.default-dispatcher-86 - 

! @7m99nng77 - Internal server error, for (POST) [/upload?resumableChunkNumber=3&resumableChunkSize=1048576&resumableCurrentChunkSize=1048576&resumableTotalSize=17296294&resumableType=&resumableIdentifier=17296294-mixedDriftarff&resumableFilename=mixedDrift.arff&resumableRelativePath=mixedDrift.arff&resumableTotalChunks=16] ->
 
play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[FileNotFoundException: .\tmp\arff296294-mixedDriftarff-mixedDrift.arff (The system cannot find the path specified)]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:255)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:182)
    at play.core.server.AkkaHttpServer$$anonfun$$nestedInanonfun$executeHandler.applyOrElse(AkkaHttpServer.scala:230)
    at play.core.server.AkkaHttpServer$$anonfun$$nestedInanonfun$executeHandler.applyOrElse(AkkaHttpServer.scala:229)
    at scala.concurrent.Future.$anonfun$recoverWith(Future.scala:412)
    at scala.concurrent.impl.Promise.$anonfun$transformWith(Promise.scala:37)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at play.api.libs.streams.Execution$trampoline$.executeScheduled(Execution.scala:109)
    at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:71)
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
    at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete(Promise.scala:284)
    at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$adapted(Promise.scala:284)
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
    at scala.concurrent.Promise.complete(Promise.scala:49)
    at scala.concurrent.Promise.complete$(Promise.scala:48)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:183)
    at scala.concurrent.Promise.failure(Promise.scala:100)
    at scala.concurrent.Promise.failure$(Promise.scala:100)
    at scala.concurrent.impl.Promise$DefaultPromise.failure(Promise.scala:183)
    at scala.concurrent.impl.Promise.$anonfun$transformWith(Promise.scala:41)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:38)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:43)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.io.FileNotFoundException: .\tmp\arff296294-mixedDriftarff-mixedDrift.arff (The system cannot find the path specified)
    at java.io.RandomAccessFile.open0(Native Method)
    at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124)
    at services.FileUploadService.savePartialFile(FileUploadService.scala:30)
    at controllers.OverviewController.$anonfun$upload(OverviewController.scala:161)
    at play.api.data.Form.fold(Form.scala:144)
    at controllers.OverviewController.$anonfun$upload(OverviewController.scala:156)
    at scala.Function1.$anonfun$andThen(Function1.scala:52)
    at play.api.mvc.ActionBuilderImpl.invokeBlock(Action.scala:482)
    at play.api.mvc.ActionBuilderImpl.invokeBlock(Action.scala:480)
    at play.api.mvc.ActionBuilder$$anon.invokeBlock(Action.scala:331)
    at play.api.mvc.ActionBuilder$$anon.invokeBlock(Action.scala:326)
    at play.api.mvc.ActionBuilder$$anon.apply(Action.scala:419)
    at play.api.mvc.Action.$anonfun$apply(Action.scala:96)
    at scala.concurrent.Future.$anonfun$flatMap(Future.scala:302)
    at scala.concurrent.impl.Promise.$anonfun$transformWith(Promise.scala:37)
    ... 12 common frames omitted

显然,代码的作者并没有在代码中以编程方式创建文件夹。因此,在 sbt 项目的基本目录中创建两个空目录作为“tmp/arrf”。