4

によって実行される*.scalaファイルのフルパスを使用する方法を探しています

scala /path/to/file/file.scala 

その理由は、私のスクリプト内で、file.scalaが保存されている場所に相対的なパスを使用したいからです。したがって、file.scalaを呼び出しているときに、file.scalaの内部から/path/to/file/file_second.scalaを呼び出したいとします。

scala ./to./file/file.scala 

私がscalaを呼び出したディレクトリは/path(つまり、System.getProperty( "user.dir")が返すもの)です。私が先験的に知っているのは、file_second.scalaが実際にはフルパスを知らなくてもfile.scalaと同じディレクトリにあるということだけです。

私が試してみました。とりわけ、getClass.getResource( "")。split( ":")(1)ですが、これは/path/./または/tmp/scala.tmp/のいずれかを返します。

scala -savecompiledは、作業したいディレクトリに* .jarを作成するので、クリーンなソリューションが必要だと思いますが、方法がわかりません...:/

助けてくれてありがとう。

4

4 に答える 4

7

スクリプトの前文:

#!/bin/sh
export SCRIPT_PATH=$(readlink -f "$0") && exec scala "$0" "$@"
!#

次の値を読み取ります。

val scriptPath = System.getenv("SCRIPT_PATH")
于 2013-06-26T19:22:13.813 に答える
1

私は過去にJavaでこれを行いました。それはきれいではなく、クラスローダーの状況の詳細によっては100%信頼できるとは限りません。

これは、独自のクラスファイルの場所を出力するScalaコードです。

import java.net.URL

object LocationTest extends App {
  val classDirURL = LocationTest.getClass.getResource("LocationTest.class")
  val classDirPath = classDirURL.getPath.replaceAll("%20", " ")
  println(classDirPath)
}

プリント

/Users/connor/desktop/LocationTest.class
于 2012-04-05T02:33:56.410 に答える
0

次のパラメータを使用してプログラムを呼び出すことができます。

scala -DPARAM_DIR=tmp Foo

プログラム内のパラメータを確認します。

object Foo extends App {
  val dir = System.getProperty ("PARAM_DIR")
  println ("Dir: " + dir) 
}

したがって、これは(必然的に)Foo.scalaが配置されているのと同じディレクトリを使用しませんが、柔軟性があり、実行時にクラスを探す場所を指示できます。

通常の場合、クラスをJarにバンドルするか、共通のクラスパスを設定すると、クラスパスに対して相対的に解決されるパッケージが作成される可能性があります。

クラスto.file.Fileの場合

 /path/to/file/file.scala 

これはクラスパス/pathになり、パッケージ内のクラスFileのfile場合は/ path /to/になります。

クラスパスが/path/ to / fileの場合、2番目のクラスは名前だけで到達可能である必要があります。

于 2012-04-05T00:20:44.117 に答える
0

次のスクリプトは、そのファイルシステムパスを出力します。そのうちの1つが成功するまで、3つの異なるアプローチが連続して試行されます。

import java.io.File

printf("[%s]\n",new File(getScriptName).getCanonicalPath)
System.exit(0)

def getScriptName:String = {
  // this approach works on the sun jvm:
  val jcmd = System.getProperty("sun.java.command","")
  jcmd.split("""\s+""").toList.reverse.head match {
  case name if new File(name).exists => name
  case _ =>
    // for this to work, you need to set -Dscala.script.name at script launch
    System.getProperty("scala.script.name","") match {
    case name if new File(name).exists => name
    case _ =>
      // last resort: derive script basename from stackdump
      val basename = {
        val filenames = new RuntimeException("").getStackTrace.map { it
          => it.getFileName
        }
        filenames.indexOf("NativeMethodAccessorImpl.java") match {
          case -1 =>  filenames.reverse.head
          case num => filenames(num - 1)
        }
      }
      // then search the system PATH for the script file
      import scala.collection.JavaConversions._
      val sep = System.getProperty("path.separator")
      val path = System.getenv("PATH").split(sep)
      path.map(new File(_,basename)).find( _.exists ) match {
        case Some(scriptfile) => scriptfile.getCanonicalPath
        case _ => basename // better than nothing
      }
    }
  }
}

最も簡単で移植性の高い方法は2番目のアプローチです。これは、次の例のように、$ SCALA_HOME / bin/scalaを呼び出す前にプロパティ'scala.script.name'を定義するためのラッパースクリプトの使用に依存します。もちろん、ラッパースクリプトは$ SCALA_HOME/binの前のPATHにある必要があります。結果はより防弾になりますが、スクリプトにのみ適用できます。

#!/usr/bin/env sh
for SCRIPT_NAME; do true ; done # set SCRIPT_NAME to the last argument
JAVA_OPTS="$JAVA_OPTS -Dscala.script.name=${SCRIPT_NAME}"
$SCALA_HOME/bin/scala "$@"

スカラランチャーの周りにこのラッパーを使用すると、次のように使用が簡単になります。

#!/usr/bin/env scala
!#
printf("%s\n",System.getProperty("scala.script.name"))
于 2012-04-24T18:30:08.027 に答える