Javaで現在の作業ディレクトリを取得するにはどうすればよいですか?


1029

Javaを使用して現在の作業ディレクトリにアクセスしたい。

私のコード:

 String current = new java.io.File( "." ).getCanonicalPath();
        System.out.println("Current dir:"+current);
 String currentDir = System.getProperty("user.dir");
        System.out.println("Current dir using System:" +currentDir);

出力:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

Cドライブが現在のディレクトリではないため、出力が正しくありません。

現在のディレクトリを取得するにはどうすればよいですか?


2
cdこれを実行するときに、コマンドプロンプトでコマンドを実行したときに表示される内容をここに貼り付けることができますか?
Nishant

3
作業ディレクトリにアクセスして達成しようとしていることは何ですか?代わりにクラスパスを使用して行うことはできますか?たとえば、ファイルシステム上のテキストファイルを読み取る必要がある場合、クラスパス上にあると簡単に見つけることができます。
Earldouglas

1
どうやって?詳しく説明してもらえますか?
Cグラフィックス

1
クラスパス上のファイルへのアクセスに関するいくつかの情報については、stackoverflow.com
questions / 1464291 /…を

7
デバッグのために、作業ディレクトリは、プログラムが存在するファイルにアクセスできないように見えるかどうかを知るのに役立ちます。
nsandersen 2016年

回答:


1152
public class JavaApplication {
  public static void main(String[] args) {
       System.out.println("Working Directory = " + System.getProperty("user.dir"));
  }
}

これにより、アプリケーションが初期化された場所からの完全な絶対パスが出力されます。


ドキュメントから:

java.ioパッケージは、現在のユーザーディレクトリを使用して相対パス名を解決します。現在のディレクトリは、システムプロパティとして表されます。つまりuser.dir、JVMが呼び出されたディレクトリです。


25
@ubuntudroid:これが、アプリケーションが初期化された場所からのパスを出力することを具体的に述べた理由です。スレッドスターターは、commnadプロンプト(基本的にはC:\ WINDOWS \ system32にあります)を開始した後、jar /プログラムを直接実行すると思います。私の要点を理解していただければ幸いです。あなたが反対票を投じたと仮定して、少なくともあなたが返事を残すことを気にかけたことを感謝します。:)
Anuj Patel 2012

1
user.dirは、プロセスが起動されたフォルダへのパスを取得します。アプリケーションのメインフォルダーへの実際のパスを取得するには、以下の私の答えを参照してください。
Peter De Winter

1
現在のディレクトリを見つけるためにそれ依存するすべてのコードは失敗します。」という意味です。一般的にすべてのコードとは限りません。(元のコメントの編集に時間がかかりました)
SubOptimal 2014

13
@SubOptimalユーザーが-Duser.dirを設定した場合、カスタム作業ディレクトリでこれを実行したいと考えています。
barwnikk 2015

5
@indyaah事実、この回答は誤りです。システムプロセス(cwd)のユーザー作業ディレクトリと現在作業ディレクトリには微妙な違いがあります。ほとんどの場合、「user.dir」は(java)プロセスのcwdを指します。ただし、「user.dir」はセマンティクスが異なり、Javaプロセスのcwdを取得するために使用されません。btw:javaプロセスdocs.oracle.com/javase/tutorial/essential/environment/で利用できるプロパティは他にもあります
comeGetSome

382

参照:http : //docs.oracle.com/javase/tutorial/essential/io/pathOps.html

とを使用するjava.nio.file.Pathjava.nio.file.Paths、Javaが現在のパスと考えるものを示すために次のことができます。これは7以降で、NIOを使用します。

Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);

これCurrent relative path is: /Users/george/NetBeansProjects/Tutorialsは、私の場合、クラスを実行した場所を出力します。絶対パスを構築していることを示すために先行セパレータを使用しないことにより、相対方法でパスを構築すると、この相対パスが開始点として使用されます。


2
最初のものはチェックされていませんが、2番目のものは実際にはホームフォルダを取得します。アプリケーションが実行されている現在の作業ディレクトリではありません。
Peter De Winter

12
ユーザーのホームディレクトリ( "user.home"、/ Users / georgeの場合)と現在の作業ディレクトリ( "user.dir"、アプリケーションのJVMを起動したディレクトリになります)を混同しないでください。 、たとえば/ Users / george / workspace / FooBarProjectなどのようになります。
David

1
私はこの方法を好みます。作業ディレクトリの親が必要な場合、これは機能しませPaths.get("").getParent()、それは与えnullます。代わりにこれは機能しますPaths.get("").toAbsolutePath().getParent()
Ole VV

235

以下はJava 7以上で動作します(ドキュメントについてはこちらを参照してください)。

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();

11
これはよりポータブルなものよりどのように優れていimport java.io.File; File(".").getAbsolutePath()ますか?
Evgeni Sergeev 2016年

8
ポータブルとは、Java 6以前で動作することを意味しますか?Paths.get()より強力なPathインターフェースへの直接アクセスを提供するという点でより良いと考えられるかもしれません。
Ole VV

8
.normalize()このコンテキストで使用することの潜在的な利点は何ですか?
Ole VV

7
@ OleV.V。Javadocから:(normalize methodReturns a path that is this path with redundant name elements eliminated.
Stephan

この場合、すでに正規化されています。
JMベッカー

73

これにより、現在の作業ディレクトリのパスがわかります。

Path path = FileSystems.getDefault().getPath(".");

これにより、作業ディレクトリにある「Foo.txt」というファイルへのパスがわかります。

Path path = FileSystems.getDefault().getPath("Foo.txt");

編集: 現在のディレクトリの絶対パスを取得するには:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

*更新* 現在の作業ディレクトリを取得するには:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();

11
これは単に '。'を返します 私のために。
john ktejik 2018

3
はい、多くのシステムでは作業ディレクトリへの参照になります。絶対パスを取得するには、もう1つのメソッド呼び出しを追加できますPath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Mark

2
foo.txtは必要ありません。空の文字列を入力してディレクトリを取得します
john ktejik

1
Windows(10)では、これにより、現在の作業ディレクトリ内でPath呼び出されたファイルを指すオブジェクトが取得されます."."私のために働くのではなく、空の文字列を使用します。
Kröw

36

これが私の解決策です

File currentDir = new File("");

1
このようなFileオブジェクトを別のFileの親として使用すると、副作用があります
。newFile

13
これを修正するには、new File("").getAbsoluteFile()代わりにを使用してください。
MRalwasser 2014年

4
それだけの価値があるので、私はFile( "。")の方が運が良かった。
keshlam、2014

Javaで相対パスを定義する方法 このページが役立ちました。また/、相対パスを作成するときに使用する必要があると想定しました。私は間違っていました/../ディレクトリツリーを上に移動する場合にも機能します。
Irrationalkilla 2016

@keshlamこれにより、現在のディレクトリにというファイルが作成されました.
Kröw

32

私はコメントでこの解決策を見つけました。これは他のものよりも優れており、よりポータブルです:

String cwd = new File("").getAbsolutePath();

あるいは

String cwd = Paths.get("").toAbsolutePath();

これは、comeGetSomeからの回答とまったく同じで、実際にはJava <7の方法
GoGoris

30

何があなたがその考えさせるはC:\ WINDOWS \ system32には、あなたの現在のディレクトリではありませんか?user.dirプロパティは、「ユーザーの現在の作業ディレクトリ」であることを明示的です。

言い換えると、コマンドラインからJavaを起動しない限り、c:\ windows \ system32がおそらくCWDです。つまり、プログラムを開始するためにダブルクリックしている場合、CWDはダブルクリック元のディレクトリではない可能性があります。

編集:これは古いウィンドウやJavaバージョンにのみ当てはまるようです。


2
これは本当ではないようです。少なくとも、Java 7を使用しているWindows 7マシンでuser.dirは、jarファイルをダブルクリックしたフォルダーが一貫してあります。
ジョルタ2015

26

を使用しCodeSource#getLocation()ます。

これはJARファイルでも問題なく機能します。あなたは得ることができCodeSourceによってProtectionDomain#getCodeSource()ProtectionDomain順番にすることによって得ることができますClass#getProtectionDomain()

public class Test {
    public static void main(String... args) throws Exception {
        URL location = Test.class.getProtectionDomain().getCodeSource().getLocation();
        System.out.println(location.getFile());
    }
}

2
これにより、JARファイルの場所が返されます。求められたものではありません。
ローンの侯爵

22
this.getClass().getClassLoader().getResource("").getPath()

12
アプリケーションをJARファイルからダブルクリックして起動すると、NPEがスローされます。
マシューワイズ

2
これは""、アプリケーションがJARファイルまたはCLASSPATH要素から実行されている場合に返されます。求められたものではありません。
ローンの侯爵

@ Zizouz212 getClass()はオブジェクトメソッドであるため、静的コンテキストでは単にを削除しthisても機能しません。実行することにより、現在のクラスを明示的に参照する必要がありますMyClass.class.getClassLoader().....
Kröw

それにもかかわらず、作業ディレクトリは返されません...
Angel O'Sphere

18

通常、Fileオブジェクトとして:

File getCwd() {
  return new File("").getAbsoluteFile();
}

"D:/ a / b / c"のような完全修飾文字列が必要な場合があります。

getCwd().getAbsolutePath()

1
Androidにはjava.nio.file.Filesが含まれていないため、これはAndroidテストでうまく機能します。
iamreptar 2015

静的なコンテキストでは機能しないようです(新しいFile( "")がNullPointerExceptionをスローします)。
nsandersen

2
@nsandersenはおそらく間違ったFileオブジェクトを使用しました:System.out.println(new java.io.File( "")。getAbsolutePath());
comeGetSome


5

のLinuxあなたが実行したときのjarからのファイルの端末を、これらの両方が同じ返されますString「/ホーム/ CurrentUserに」、youreのjarファイルには関係なく、です。jarファイルを起動するときに、ターミナルで現在使用しているディレクトリに依存します。

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

Classwith mainが呼び出される場合はMainClass、次を試してください:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

これは戻りますString絶対パスのjarファイル。


3
それは求められたものではありません。
ローンの侯爵

5

Windowsのuser.dirを使用すると、期待どおりにディレクトリが返されますが、昇格された権限(管理者として実行)でアプリケーションを起動した場合は、C:\ WINDOWS \ system32が返されます


3

パッケージを含む現在のディレクトリにアクセスしたいと思います。つまり、Javaプログラムが入ってc:\myApp\com\foo\src\service\MyTest.javaおり、それまでに印刷したいc:\myApp\com\foo\src\service場合は、次のコードを試すことができます。

String myCurrentDir = System.getProperty("user.dir")
            + File.separator
            + System.getProperty("sun.java.command")
                    .substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
                    .replace(".", File.separator);
    System.out.println(myCurrentDir);

注:このコードは、Oracle JREを使用するWindowsでのみテストされています。


6
この回答に反対票を投じないのは無意味です。投稿する前にもっとよく考えてください。これらすべてに該当しない限り、コードは壊れています。2. OSはWindowsです(File.separator代わりに使用するか、複数引数のFileコンストラクター)。3.クラスパスは、コマンドラインに次の特定され、そして(??)「パッケージを含む現在のディレクトリが」です:。最初に指定、b。絶対指定、c。CWDに正確に一致し(Windowsの大文字と小文字を区別しない場合でも)、d。CWDの子孫です
マイケル・シェパー2013年

これはポイント1と2に対応していますが、何か不足している場合を除いて、コマンドラインで指定されたクラスパス(つまり、環境変数ではない)、および「パッケージを含む現在のディレクトリ」(Iそれが何を意味するのか私は本当に理解していないことを認める)特にクラスパスの最初の要素の子孫であること そして、ケースマッチングの問題が残っています。私のコメントが役に立たなかったとすいません。コメントの文字数制限内に収めるために、明快さを犠牲にしました。
Michael Scheper 2013

@Inversusでは、一部の環境でのみ「完全に機能」します。あなたはたまたまそのようなものでそれをテストするのに十分幸運でした。正当なランタイム環境で失敗するソフトウェアを作成することは、テスト環境のセットがそれらを含めるのに十分に拡張的でない場合でも、良い習慣ではありません。
Charles Duffy

@CharlesDuffyそうですね、それは良い習慣ではありません。幸いなことに、この解決策は「特定の問題を解決する」ことで「正当なランタイム環境で失敗する」原因にはなりませんでした。実際、それは私がこのような失敗を解決し、より堅牢なコードを書くのに役立ちました。また、私が抱えていた非常に具体的な問題(これはこの質問/回答にのみ関連しています)を解決するのに役立ちました。私はそれを見つけることができてラッキーだったと思います。
2014

3

これはチェックインされているだけでWindows、他のオペレーティングシステムでは完璧に機能すると思います[ Linux,MacOs,Solaris] :)。


私が持っていた2つの .jar、同じディレクトリ内のファイルを。1つの.jarファイルから.jar同じディレクトリにある他のファイルを開始したかった。

問題はcmd、現在のディレクトリから起動するとですsystem32


警告!

  • 以下は、私がフォルダ名を;][[;'57f2g34g87-8+9-09!2#@!$%^^&()使用して行ったすべてのテストでかなりうまくいくようです、または()%&$%^@# うまくいきます。
  • 私はProcessBuilder以下のようにを使用しています:

🍂..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

🍂 getBasePathForClass(Class<?> classs)

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }

これにより、JARファイルの場所が返されます。求められたものではありません。
ローンの侯爵

@EJP .jarファイルの場所は、Javaプログラムの現在の作業ディレクトリではありませんか?
GOXR3PLUS

2

現在の作業ディレクトリの定義は、Javaの実装によって異なります。Java 7より前の特定のバージョンでは、作業ディレクトリを取得する一貫した方法がありませんでした。この問題を回避-Dするには、Javaファイルを起動して、情報を保持する変数を定義します。

何かのようなもの

java -D com.mycompany.workingDir="%0"

それはまったく正しくありませんが、あなたは考えを理解します。その後System.getProperty("com.mycompany.workingDir")...


6
質問には関係ありません。
Peter De Winter

1
これはJavaにとって意味があります。これは、相対パス名で開いたファイルが相対的であるディスク上の場所です。
Rob I

2
はい、意味があります。私の言葉はやや不適切に選ばれました。しかし、あなたは要点を見逃しています-Java 7より前は、現在の作業ディレクトリを知る方法がなく、異なる実装がそれらを設定しました...違う...
MJB

1

コマンドラインからEclipseまたはnetbeanまたはスタンドアロンでプロジェクトを実行しようとしていると想定します。私はそれを修正する方法を書いています

public static final String getBasePathForClass(Class<?> clazz) {
    File file;
    try {
        String basePath = null;
        file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
            basePath = file.getParent();
        } else {
            basePath = file.getPath();
        }
        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbean
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    } catch (URISyntaxException e) {
        throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
    }
}

使用するには、ファイルを読み取るためのベースパスを取得するすべての場所で、アンカークラスを上記のメソッドに渡すことができます。結果は必要なものになる可能性があります。

ベスト、


2
これにより、JARファイルの場所が返されます。求められたものではありません。
ローンの侯爵

@ user207421はい私はこの答えが質問の真の答えではないことを知っていますが、ほとんどの場合、誰もが「コマンドライン作業ディレクトリ」ではなく「jarが配置されているディレクトリ」を取得したいと考えています。
バッハデン

0

ここに投稿された答えはどれも私にとってはうまくいきませんでした。これがうまくいったことです:

java.nio.file.Paths.get(
  getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);

編集:私のコードの最終バージョン:

URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
    myURI = myURL.toURI();
} catch (URISyntaxException e1) 
{}
return java.nio.file.Paths.get(myURI).toFile().toString()

これにより、JARファイルの場所が返されます。求められたものではありません。
ローンの侯爵

0

これは、混乱の瞬間が吹き込んだときの私の特効薬です(メインで最初に呼び出す)。たぶん、たとえば、JVMはIDEによって別のバージョンになっています。この静的関数は、現在のプロセスPIDを検索し、そのpidでVisualVMを開きます。あなたがそれをすべて望んで、それを手に入れるので、混乱はすぐそこに止まります...

  public static void callJVisualVM() {
    System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
    //next search current jdk/jre
    String jre_root = null;
    String start = "vir";
    try {
        java.lang.management.RuntimeMXBean runtime =
                java.lang.management.ManagementFactory.getRuntimeMXBean();
        String jvmName = runtime.getName();
        System.out.println("JVM Name = " + jvmName);
        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        Runtime thisRun = Runtime.getRuntime();
        jre_root = System.getProperty("java.home");
        System.out.println("jre_root:" + jre_root);
        start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
        thisRun.exec(start);
    } catch (Exception e) {
        System.getProperties().list(System.out);
        e.printStackTrace();
    }
}


-7

これは現在のディレクトリ名です

String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();

これは現在のディレクトリパスです

String path=folder.getPath();

1
OPは、アプリケーションの実行元の現在の作業ディレクトリを必要としていました。
Leif Gruenwoldt 2014年

これはあなたのホームディレクトリであり、おそらくあなたのものを除いて、誰かの現在の作業ディレクトリではありません。求められたものではありません。
ローンの侯爵
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.