Отримайте шлях до програми


79

Нещодавно я шукав, як я можу отримати каталог програми на Java. Нарешті я знайшов відповідь, але мені потрібно напрочуд багато часу, оскільки пошук такого загального поняття непростий. Думаю, було б непогано скласти перелік, як цього досягти, кількома мовами.

Не соромтеся голосувати за / проти, якщо вам (не) подобається ідея, і, будь ласка, внесіть свій внесок, якщо вона вам подобається.

Уточнення:

Існує чітка різниця між каталогом, який містить виконуваний файл, і поточним робочим каталогом (задається pwdпід Unix). Спочатку я цікавився першим, але сміливо публікую методи і для визначення другого (уточнюючи, який із них ви маєте на увазі).


3
Який шлях ви маєте на увазі? Поточний робочий каталог або каталог, в якому знаходиться виконуваний код?
Paul de Vrieze,

Відповіді:


59

У Java дзвінки

System.getProperty("user.dir")

і

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

повернути поточний робочий каталог.

Заклик до

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

повертає шлях до файлу JAR, що містить поточний клас, або елемент (шлях) CLASSPATH, який дав поточний клас, якщо ви працюєте безпосередньо з файлової системи.

Приклад:

  1. Ваша заявка знаходиться за адресою

     C:\MyJar.jar
    
  2. Відкрийте оболонку (cmd.exe) і перейдіть cdдо підкаталогу C: \ test \.

  3. Запустіть програму за допомогою команди java -jar C:\MyJar.jar.

  4. Перші два виклики повертають 'C: \ test \ subdirectory'; третій виклик повертає 'C: \ MyJar.jar'.

Під час запуску з файлової системи, а не з файлу JAR, результатом буде шлях до кореня сформованих файлів класів, наприклад

c:\eclipse\workspaces\YourProject\bin\

Шлях не включає каталоги пакунків для сформованих файлів класів.

Повний приклад отримання каталогу програми без імені файлу .jar або відповідного шляху до файлів класу, якщо він працює безпосередньо з файлової системи (наприклад, під час налагодження):

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

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

Шукав спосіб помістити файли, доступні лише для читання, в той самий пакет, що і класи Java ... getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (). GetPath () працював чудово, дякую!
Нечіткий аналіз

@fuzzyanalysis Саме Class.getResource()для цього.
user207421

22

У .NET (C #, VB,…) ви можете запитати поточний Assemblyекземпляр для його Location. Однак до цього додано ім'я виконуваного файлу. Наступний код дезінфікує шлях ( using System.IOі using System.Reflection):

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

Крім того, ви можете використовувати інформацію, надану, AppDomainдля пошуку збірок, на які посилаються:

System.AppDomain.CurrentDomain.BaseDirectory

VB дозволяє інший ярлик через Myпростір імен:

My.Application.Info.DirectoryPath

1
Ви також можете використовувати Application.StartupPath для деяких програм. Однак це не буде працювати для ASP.NET.
jocull

1
Власне його, Application.ExecutablePath
zam664

9

У Windows використовуйте функцію WinAPI GetModuleFileName () . Передайте NULL для ручки модуля, щоб отримати шлях до поточного модуля.


7

Python

path = os.path.dirname(__file__)

Це отримує шлях до поточного модуля.


5

Какао Objective-C (Mac OS X, я не знаю, що стосується особливостей iPhone):

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

2
У моїй програмі для Mac OSX я шукав фактичний шлях до виконуваного файлу (для включення до plist) і використовував це: NSString * executablePath = [[NSBundle mainBundle] executablePath]; - існує також версія 'executableURL' для повернення URL-адреси замість рядка
Тодд

4

У Java існує два способи знайти шлях до програми. Одним з них є використання System.getProperty:

System.getProperty("user.dir");

Інша можливість - використання java.io.File:

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

Ще одна можливість використовує рефлексію:

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

1
Зверніть увагу, що це трохи вводить в оману / заплутано. Три наведені вами методи можуть дати абсолютно різні результати!
Zarkonnen

Зарконен: Ви маєте рацію, але, як випливає з мого оригінального повідомлення, я не фахівець. Це вікі спільноти. Будь ласка, не соромтеся редагувати / виправляти мою відповідь!
Конрад Рудольф,

ПОРАДА: Зазвичай шлях не потрібно вказувати, якщо ви хочете отримати доступ до файлу в поточному робочому каталозі, наприклад: file = new File ("file.cfg"); Тільки обов’язково завжди встановлюйте робочий каталог на місце розташування вашої програми під час ініціалізації або під ярликом програми.
лепе

@lepe Не встановлюйте робочий каталог під час запуску, це має деякі небажані наслідки, наприклад, вказівку деяких діалогових вікон вибору файлів за замовчуванням на шлях програми, а не вибраний користувачем робочий каталог.
Конрад Рудольф

1
Дві основні проблеми останнього підходу: одна, ProtectionDomain.getCodeSource () може повернути значення null . По-друге, URL.getPath () не повертає ім'я файлу, він просто повертає (можливо, захищений) шлях до URL-адреси. C:\Program Files\ExampleAppпредставлений у формі URL як file:/C:/Program%20Files/ExampleApp, для якого повертається getPath () "/C:/Program%20Files/ExampleApp", який, очевидно, не існує. Єдиним правильним способом перетворення URL-адреси у файл є new File(url.toURI()).
VGR

4

У VB6 ви можете отримати шлях до програми за допомогою App.Pathвластивості.

Зверніть увагу, що це не матиме кінцевих \ОСОБЛИВО, коли програма знаходиться в корені диска.

В IDE:

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

4

У .Net ви можете використовувати

System.IO.Directory.GetCurrentDirectory

щоб отримати поточний робочий каталог програми, а у VB.NET конкретно ви можете використовувати

My.Application.Info.DirectoryPath

отримати каталог exe.


3

Дельфи

У програмах Windows:

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

У консольних додатках:

Незалежно від мови, першим параметром командного рядка є повністю кваліфіковане ім'я виконуваного файлу:

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


2

Unix

У unix можна знайти шлях до виконуваного файлу, який було запущено за допомогою змінних середовища. Це не обов'язково абсолютний шлях, тому вам потрібно буде поєднати поточний робочий каталог (у оболонці pwd:) та / або змінну PATH зі значенням 0'-го елемента середовища.

Значення в Unix обмежене, оскільки виконуваний файл, наприклад, можна викликати через символічне посилання, і для змінної середовища використовується лише початкове посилання. Загалом програми на unix не надто надійні, якщо вони використовують це для будь-якої цікавої речі (наприклад, для завантаження ресурсів). В Unix зазвичай використовують жорстко закодовані місця для речей, наприклад файл конфігурації, /etcде вказані місця розташування ресурсів.



2

У 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

в Android його

getApplicationInfo().dataDir;

щоб отримати SD-карту, я використовую

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

де останній використовується для зберігання певного типу файлу (аудіо / фільми тощо). У вас є константи для цих рядків у класі Environment.

В основному, для будь-чого з додатком використовуйте клас ApplicationInfo та для будь-якого відношення до даних на SD-карті / Зовнішньому каталозі за допомогою класу Environment.

Документи: ApplicationInfo , Навколишнє середовище


2

У Tcl

Шлях поточного сценарію:

set path [info script]

Шлях оболонки Tcl:

set path [info nameofexecutable]

Якщо вам потрібен каталог будь-якого з них, виконайте:

set dir [file dirname $path]

Отримати поточний (робочий) каталог:

set dir [pwd]

2

Java:

У всіх системах (Windows, Linux, Mac OS X) для мене працює лише це:

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;
}

Це видає NPE, якщо програма працює у файлі JAR.
user207421

1

у Ruby наступний фрагмент повертає шлях до поточного вихідного файлу:

path = File.dirname(__FILE__)

1

У CFML є дві функції для доступу до шляху сценарію:

getBaseTemplatePath()
getCurrentTemplatePath()

Виклик getBaseTemplatePath повертає шлях "базового" сценарію - тобто того, який був запитаний веб-сервером.
Виклик getCurrentTemplatePath повертає шлях до поточного сценарію - тобто того, який виконується в даний момент.

Обидва шляхи є абсолютними і містять повний каталог + ім'я файлу сценарію.

Щоб визначити лише каталог, використовуйте функцію getDirectoryFromPath( ... )результатів.

Отже, щоб визначити розташування в каталозі програми, ви можете зробити:

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

Всередині onApplicationStartподії для вашогоApplication.cfc



Щоб визначити шлях, на якому знаходиться сервер додатків, на якому запущений ваш движок CFML, ви можете отримати доступ до команд оболонки за допомогою cfexecute, тому (маючи на увазі вище обговорення pwd / etc) ви можете зробити:

Unix:

<cfexecute name="pwd"/>

для Windows створіть pwd.batтекст @cd, що містить , а потім:

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

(Використовуйте variableатрибут cfexecuteдля зберігання значення замість виведення на екран.)


1

У cmd (оболонка командного рядка Microsoft)

Ви можете отримати назву сценарію за допомогою% * (може бути відносно pwd)

Це отримує каталог сценарію:

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

Якщо ви знайдете якісь помилки, то і знайдете. Тоді, будь ласка, виправте або прокоментуйте.


1

Я випустив https://github.com/gpakosz/whereami, який вирішує проблему на C і надає вам:

  • шлях до поточного виконуваного файлу
  • шлях до поточного модуля (відрізняється від шляху до виконуваного при виклику із спільної бібліотеки).

Він використовує GetModuleFileNameWв Windows, аналізує /proc/self/mapsв Linux та Android і використовує _NSGetExecutablePathабо dladdrна Mac та iOS.


0

Примітка до відповіді "20 вище лише щодо Mac OSX: Якщо виконуваний файл JAR перетворюється на" додаток "через OSX JAR BUNDLER, тоді getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (); НЕ поверне поточного каталогу програми, але до відповіді додасть внутрішню структуру каталогу програми. Ця внутрішня структура програми є / theCurrentFolderWhereTheAppReside / Contents / Resources / Java / yourfile

Можливо, це невелика помилка в Java. У будь-якому випадку, потрібно отримати метод один або два, щоб отримати правильну відповідь, і обидва нададуть правильну відповідь, навіть якщо додаток запущено, наприклад, за допомогою ярлика, який знаходиться в іншій папці або на робочому столі.

Карл

SoundPimp.com

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.