Uzyskaj ścieżkę do aplikacji


79

Niedawno szukałem sposobu, aby uzyskać katalog aplikacji w Javie. W końcu znalazłem odpowiedź, ale potrzebowałem zadziwiająco długo, ponieważ poszukiwanie tak ogólnego terminu nie jest łatwe. Myślę, że dobrym pomysłem byłoby sporządzenie listy sposobów osiągnięcia tego w wielu językach.

Zapraszam do głosowania za / przeciw, jeśli pomysł Ci się nie podoba i prosimy o wniesienie wkładu, jeśli Ci się spodoba.

Wyjaśnienie:

Istnieje wyraźne rozróżnienie między katalogiem zawierającym plik wykonywalny a bieżącym katalogiem roboczym (podanym w pwdsystemie Unix). Pierwotnie interesowałem się tym pierwszym, ale zachęcam do publikowania metod określania również drugiego (wyjaśniając, który z nich masz na myśli).


3
Jaką ścieżkę masz na myśli? Bieżący katalog roboczy czy katalog, w którym znajduje się kod wykonywalny?
Paul de Vrieze,

Odpowiedzi:


59

W Javie rozmowy

System.getProperty("user.dir")

i

new java.io.File(".").getAbsolutePath();

zwraca bieżący katalog roboczy.

Wezwanie do

getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

zwraca ścieżkę do pliku JAR zawierającego bieżącą klasę lub element CLASSPATH (ścieżkę), który zwrócił bieżącą klasę, jeśli uruchamiasz bezpośrednio z systemu plików.

Przykład:

  1. Twoja aplikacja znajduje się pod adresem

     C:\MyJar.jar
    
  2. Otwórz powłokę (cmd.exe) i przejdź cddo podkatalogu C: \ test \.

  3. Uruchom aplikację za pomocą polecenia java -jar C:\MyJar.jar.

  4. Pierwsze dwa wywołania zwracają „C: \ test \ subdirectory”; trzecie wywołanie zwraca „C: \ MyJar.jar”.

Podczas uruchamiania z systemu plików, a nie z pliku JAR, wynikiem będzie na przykład ścieżka do katalogu głównego wygenerowanych plików klas

c:\eclipse\workspaces\YourProject\bin\

Ścieżka nie zawiera katalogów pakietów dla wygenerowanych plików klas.

Kompletny przykład pobierania katalogu aplikacji bez nazwy pliku .jar lub odpowiedniej ścieżki do plików klas, jeśli jest uruchamiana bezpośrednio z systemu plików (np. Podczas debugowania):

String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); 

if (applicationDir.endsWith(".jar"))
{
    applicationDir = new File(applicationDir).getParent();
}
// else we already have the correct answer

Szukałem sposobu na umieszczenie plików tylko do odczytu w tym samym pakiecie co klasy java ... getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (). GetPath () działało doskonale, dzięki!
Analiza rozmyta

@fuzzyanalysis Właśnie do tego Class.getResource()służy.
user207421

22

W .NET (C #, VB,…) można wysyłać zapytania do bieżącej Assemblyinstancji o plik Location. Jednak do tego dołączona jest nazwa pliku wykonywalnego. Poniższy kod czyści ścieżkę ( using System.IOi using System.Reflection):

Directory.GetParent(Assembly.GetExecutingAssembly().Location)

Alternatywnie możesz użyć informacji dostarczonych przez, AppDomainaby wyszukać przywoływane zestawy:

System.AppDomain.CurrentDomain.BaseDirectory

VB umożliwia inny skrót za pośrednictwem Myprzestrzeni nazw:

My.Application.Info.DirectoryPath

1
W przypadku niektórych programów można również użyć Application.StartupPath. Jednak nie będzie działać w przypadku ASP.NET.
żartobliwy

1
Właściwie to Application.ExecutablePath
zam664


7

Pyton

path = os.path.dirname(__file__)

To pobiera ścieżkę do bieżącego modułu.


5

Objective-C Cocoa (Mac OS X, nie znam specyfiki iPhone'a):

NSString * applicationPath = [[NSBundle mainBundle] bundlePath];

2
W mojej aplikacji Mac OSX szukałem rzeczywistej ścieżki do pliku wykonywalnego (w celu umieszczenia go w pliku plist) i użyłem tego: NSString * executablePath = [[NSBundle mainBundle] executablePath]; - istnieje również wersja „executableURL”, która zwraca adres URL zamiast ciągu znaków
Todd

4

W Javie istnieją dwa sposoby znalezienia ścieżki aplikacji. Należy zatrudnić System.getProperty:

System.getProperty("user.dir");

Inną możliwością jest użycie java.io.File:

new java.io.File("").getAbsolutePath();

Jeszcze inna możliwość wykorzystuje refleksję:

getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

1
Zauważ, że jest to trochę mylące / mylące. Trzy metody, które podajesz, mogą dać zupełnie inne rezultaty!
Zarkonnen

Zarkonnen: Masz rację, ale jak sugerowałem w moim oryginalnym poście, nie jestem ekspertem. To jest wiki społeczności. Zapraszam do edycji / poprawiania mojej odpowiedzi!
Konrad Rudolph

WSKAZÓWKA: Zazwyczaj ścieżka nie musi być określana, jeśli chcesz uzyskać dostęp do pliku w bieżącym katalogu roboczym, na przykład: file = new File ("file.cfg"); Pamiętaj tylko, aby zawsze ustawiać katalog roboczy na lokalizację aplikacji podczas inicjalizacji lub w skrócie do aplikacji.
lepe

@lepe Nie ustawiaj katalogu roboczego podczas uruchamiania, ma to niepożądane konsekwencje, takie jak domyślne wskazanie niektórych okien dialogowych wyboru plików na ścieżkę aplikacji, a nie na katalog roboczy wybrany przez użytkownika.
Konrad Rudolph,

1
Dwa główne problemy z ostatnim podejściem: jeden, ProtectionDomain.getCodeSource () może zwrócić wartość null . Po drugie, URL.getPath () nie zwraca nazwy pliku, po prostu zwraca (prawdopodobnie ze znakami ucieczki) fragment adresu URL. C:\Program Files\ExampleAppjest reprezentowany w postaci adresu URL jako file:/C:/Program%20Files/ExampleApp, dla którego funkcja getPath () zwraca "/C:/Program%20Files/ExampleApp", co oczywiście nie istnieje. Jedynym prawidłowym sposobem konwersji adresu URL do pliku jest new File(url.toURI()).
VGR

4

W VB6 ścieżkę aplikacji można uzyskać za pomocą App.Pathwłaściwości.

Zauważ, że nie będzie to miało końca \EXCEPT, gdy aplikacja znajduje się w katalogu głównym dysku.

W IDE:

?App.Path
C:\Program Files\Microsoft Visual Studio\VB98

4

W .Net możesz użyć

System.IO.Directory.GetCurrentDirectory

aby uzyskać bieżący katalog roboczy aplikacji, aw VB.NET konkretnie możesz użyć

My.Application.Info.DirectoryPath

aby uzyskać katalog exe.


3

Delphi

W aplikacjach Windows:

Unit Forms;
path := ExtractFilePath(Application.ExeName);

W aplikacjach konsolowych:

Niezależnie od języka, pierwszym parametrem wiersza poleceń jest w pełni kwalifikowana nazwa pliku wykonywalnego:

Unit System;
path := ExtractFilePath(ParamStr(0));

3

Libc w
środowisku typu * nix (także Cygwin w Windows):

  #include <unistd.h>

   char *getcwd(char *buf, size_t size);

   char *getwd(char *buf); //deprecated

   char *get_current_dir_name(void);

Zobacz stronę podręcznika


2

Unix

W systemie UNIX można znaleźć ścieżkę do pliku wykonywalnego, który został uruchomiony przy użyciu zmiennych środowiskowych. To nie koniecznie ścieżka bezwzględna, więc trzeba by połączyć bieżący katalog roboczy (w powłoce:pwd ) i / lub zmiennej PATH z wartością elementu 0'th środowiska.

Wartość jest jednak ograniczona w systemie UNIX, ponieważ plik wykonywalny można na przykład wywołać za pośrednictwem dowiązania symbolicznego, a dla zmiennej środowiskowej używany jest tylko link początkowy. Ogólnie aplikacje na unixie nie są bardzo solidne, jeśli używają tego do jakichkolwiek interesujących rzeczy (takich jak ładowanie zasobów). W systemie UNIX często używa się miejsc zakodowanych na stałe, na przykład pliku konfiguracyjnego, w /etcktórym określone są lokalizacje zasobów.



2

W PHP :

<?php
  echo __DIR__; //same as dirname(__FILE__). will return the directory of the running script
  echo $_SERVER["DOCUMENT_ROOT"]; // will return the document root directory under which the current script is executing, as defined in the server's configuration file.
  echo getcwd(); //will return the current working directory (it may differ from the current script location).
?>

2

w Androidzie jego

getApplicationInfo().dataDir;

aby uzyskać kartę SD, używam

Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(String type);

gdzie ten ostatni jest używany do przechowywania określonego typu plików (audio / filmy itp.). Masz stałe dla tych ciągów w klasie Environment.

Zasadniczo do wszystkiego, co ma związek z aplikacją, użyj klasy ApplicationInfo, a do wszystkiego, co ma związek z danymi na karcie SD / katalogu zewnętrznym, używając klasy Environment.

Dokumenty: ApplicationInfo , Środowisko


2

W Tcl

Ścieżka aktualnego skryptu:

set path [info script]

Ścieżka powłoki Tcl:

set path [info nameofexecutable]

Jeśli potrzebujesz katalogu któregokolwiek z tych, wykonaj:

set dir [file dirname $path]

Pobierz aktualny (roboczy) katalog:

set dir [pwd]

2

Jawa:

Na wszystkich systemach (Windows, Linux, Mac OS X) działa u mnie tylko to:

public static File getApplicationDir() 
{
    URL url = ClassLoader.getSystemClassLoader().getResource(".");
    File applicationDir = null;
    try {
        applicationDir = new File(url.toURI());
    } catch(URISyntaxException e) {
        applicationDir = new File(url.getPath());
    }

    return applicationDir;
}

Powoduje to wyświetlenie NPE, jeśli aplikacja jest uruchomiona w pliku JAR.
user207421

1

w Rubim poniższy fragment kodu zwraca ścieżkę do bieżącego pliku źródłowego:

path = File.dirname(__FILE__)

1

W języku CFML istnieją dwie funkcje dostępu do ścieżki skryptu:

getBaseTemplatePath()
getCurrentTemplatePath()

Wywołanie getBaseTemplatePath zwraca ścieżkę do skryptu „podstawowego” - tj. Tego, którego zażądał serwer WWW.
Wywołanie getCurrentTemplatePath zwraca ścieżkę do bieżącego skryptu - tj. Tego, który jest aktualnie wykonywany.

Obie ścieżki są bezwzględne i zawierają pełny katalog + nazwę pliku skryptu.

Aby określić tylko katalog, użyj funkcji getDirectoryFromPath( ... ) na wynikach.

Aby więc określić lokalizację katalogu aplikacji, możesz zrobić:

<cfset Application.Paths.Root = getDirectoryFromPath( getCurrentTemplatePath() ) />

Wewnątrz onApplicationStartwydarzenia dla TwojegoApplication.cfc



Aby określić ścieżkę, w której znajduje się serwer aplikacji, na którym działa silnik CFML, możesz uzyskać dostęp do poleceń powłoki za pomocą cfexecute, więc (mając na uwadze powyższe dyskusje na temat pwd / itp.) Możesz wykonać:

Unix:

<cfexecute name="pwd"/>

w systemie Windows utwórz pwd.battekst zawierający @cd, a następnie:

<cfexecute name="C:\docume~1\myuser\pwd.bat"/>

(Użyj variableatrybutu cfexecutedo przechowywania wartości zamiast wyświetlania na ekranie).


1

W cmd (powłoka wiersza poleceń Microsoft)

Nazwę skryptu można uzyskać za pomocą% * (może być względne w stosunku do pwd)

To dostaje katalog skryptu:

set oldpwd=%cd%
cd %0\..
set app_dir=%pwd%
cd %oldpwd%

Jeśli znajdziesz jakieś błędy, to na pewno. Następnie napraw lub skomentuj.


1

Udostępniłem https://github.com/gpakosz/whereami, który rozwiązuje problem w C i daje:

  • ścieżka do bieżącego pliku wykonywalnego
  • ścieżka do bieżącego modułu (różni się od ścieżki do pliku wykonywalnego w przypadku wywołania z biblioteki współdzielonej).

Używa GetModuleFileNameWw systemie Windows, analizuje /proc/self/mapsw systemie Linux i Android i używa _NSGetExecutablePathlub dladdrna komputerach Mac i iOS.


0

Uwaga dotycząca odpowiedzi „20 powyżej tylko w odniesieniu do systemu Mac OSX: Jeśli plik wykonywalny JAR zostanie przekształcony w„ aplikację ”za pośrednictwem pakietu OSX JAR BUNDLER, funkcja getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (); NIE zwróci wartości bieżący katalog aplikacji, ale doda wewnętrzną strukturę katalogów aplikacji do odpowiedzi. Ta wewnętrzna struktura aplikacji to / theCurrentFolderWhereTheAppReside / Contents / Resources / Java / yourfile

Być może jest to mały błąd w Javie. W każdym razie, aby uzyskać poprawną odpowiedź, należy skorzystać z pierwszej lub drugiej metody, a obie dostarczą poprawną odpowiedź, nawet jeśli aplikacja jest uruchomiona, np. Poprzez skrót znajdujący się w innym folderze lub na pulpicie.

Carl

SoundPimp.com

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.