Nhận đường dẫn của ứng dụng


79

Gần đây, tôi đã tìm kiếm cách lấy thư mục của ứng dụng trong Java. Cuối cùng thì tôi cũng đã tìm ra câu trả lời nhưng tôi đã cần một thời gian dài đáng ngạc nhiên vì việc tìm kiếm một thuật ngữ chung chung như vậy không dễ dàng. Tôi nghĩ sẽ là một ý kiến ​​hay nếu biên soạn một danh sách về cách đạt được điều này bằng nhiều ngôn ngữ.

Hãy up / downvote nếu bạn (không) thích ý tưởng đó và hãy đóng góp nếu bạn thích nó.

Làm rõ:

Có một sự khác biệt rõ ràng giữa thư mục chứa tệp thực thithư mục làm việc hiện tại (được cung cấp bởi pwdUnix). Tôi ban đầu quan tâm đến cái trước nhưng cũng vui lòng đăng các phương pháp để xác định cái sau (làm rõ ý bạn là cái nào).


3
Ý bạn là con đường nào? Thư mục làm việc hiện tại hay thư mục chứa mã thực thi?
Paul de Vrieze

Câu trả lời:


59

Trong Java, các cuộc gọi

System.getProperty("user.dir")

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

trả về thư mục làm việc hiện tại.

Cuộc gọi đến

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

trả về đường dẫn đến tệp JAR chứa lớp hiện tại hoặc phần tử CLASSPATH (đường dẫn) mang lại lớp hiện tại nếu bạn đang chạy trực tiếp từ hệ thống tệp.

Thí dụ:

  1. Ứng dụng của bạn được đặt tại

     C:\MyJar.jar
    
  2. Mở shell (cmd.exe) và cdđến C: \ test \ subdirectory.

  3. Khởi động ứng dụng bằng lệnh java -jar C:\MyJar.jar.

  4. Hai lệnh gọi đầu tiên trả về 'C: \ test \ subdirectory'; cuộc gọi thứ ba trả về 'C: \ MyJar.jar'.

Ví dụ: khi chạy từ hệ thống tệp thay vì tệp JAR, kết quả sẽ là đường dẫn đến thư mục gốc của tệp lớp được tạo

c:\eclipse\workspaces\YourProject\bin\

Đường dẫn không bao gồm các thư mục gói cho các tệp lớp được tạo.

Một ví dụ đầy đủ để lấy thư mục ứng dụng không có tên tệp .jar hoặc đường dẫn tương ứng đến tệp lớp nếu chạy trực tiếp từ hệ thống tệp (ví dụ: khi gỡ lỗi):

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

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

Đang tìm cách đặt các tệp chỉ đọc vào cùng một gói với các lớp java ... getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (). GetPath () hoạt động hoàn hảo, cảm ơn!
Phân tích mờ

@fuzzyanalysis Đó chính xác Class.getResource()là những gì dành cho.
user207421 14/12/16

22

Trong .NET (C #, VB,…) , bạn có thể truy vấn phiên bản hiện tại Assemblycủa nó Location. Tuy nhiên, điều này có thêm tên tệp của tệp thực thi. Đoạn mã sau làm sạch đường dẫn ( using System.IOusing System.Reflection):

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

Ngoài ra, bạn có thể sử dụng thông tin được cung cấp bởi AppDomainđể tìm kiếm các cụm được tham chiếu:

System.AppDomain.CurrentDomain.BaseDirectory

VB cho phép một lối tắt khác thông qua Mykhông gian tên:

My.Application.Info.DirectoryPath

1
Bạn cũng có thể sử dụng Application.StartupPath cho một số chương trình. Tuy nhiên, nó sẽ không hoạt động cho ASP.NET.
jocull

1
Trên thực tế của nó, Application.ExecutablePath
zam664


7

Python

path = os.path.dirname(__file__)

Đó là đường dẫn của mô-đun hiện tại.


5

Objective-C Cocoa (Mac OS X, tôi không biết cụ thể về iPhone):

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

2
Trong ứng dụng Mac OSX của mình, tôi đang tìm kiếm đường dẫn thực tế đến tệp thực thi (để đưa vào một plist) và sử dụng điều này: NSString * executeutablePath = [[NSBundle mainBundle] executeutablePath]; - cũng có một phiên bản 'thi hành đượcURL' để trả về một URL thay vì một chuỗi
Todd

4

Trong Java , có hai cách để tìm đường dẫn của ứng dụng. Một là sử dụng System.getProperty:

System.getProperty("user.dir");

Một khả năng khác là sử dụng java.io.File:

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

Tuy nhiên, một khả năng khác sử dụng phản chiếu:

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

1
Lưu ý rằng điều này là một chút sai lầm / khó hiểu. Ba phương pháp bạn trích dẫn có thể cho kết quả hoàn toàn khác nhau!
Zarkonnen

Zarkonnen: Bạn nói đúng nhưng như ngụ ý trong bài đăng ban đầu của tôi, tôi không phải là chuyên gia. Đây là một wiki cộng đồng. Xin vui lòng chỉnh sửa / sửa chữa câu trả lời của tôi!
Konrad Rudolph

MẸO: Thông thường không cần chỉ định đường dẫn nếu bạn muốn truy cập một tệp trong thư mục làm việc hiện tại, như: file = new File ("file.cfg"); Chỉ cần đảm bảo luôn đặt thư mục làm việc vào vị trí của ứng dụng của bạn trong quá trình khởi tạo hoặc tại lối tắt ứng dụng.
lepe

@lepe Không đặt thư mục làm việc khi khởi chạy, điều này gây ra một số hậu quả không mong muốn, chẳng hạn như trỏ một số hộp thoại trình chọn tệp theo mặc định đến đường dẫn của ứng dụng, thay vì thư mục làm việc do người dùng chọn.
Konrad Rudolph

1
Hai vấn đề lớn với cách tiếp cận cuối cùng: Một, ProtectionDomain.getCodeSource () có thể trả về null . Thứ hai, URL.getPath () không trả về tên tệp, nó chỉ trả về phần đường dẫn (có thể thoát) của URL. C:\Program Files\ExampleAppđược biểu diễn dưới dạng URL file:/C:/Program%20Files/ExampleApp, mà getPath () trả về "/C:/Program%20Files/ExampleApp", hiển nhiên không tồn tại. Cách chính xác duy nhất để chuyển đổi một URL thành một tệp là new File(url.toURI()).
VGR

4

Trong VB6, bạn có thể lấy đường dẫn ứng dụng bằng thuộc App.Pathtính.

Lưu ý rằng điều này sẽ không có dấu \TRỪ NGOẠI LỆ khi ứng dụng nằm trong thư mục gốc của ổ đĩa.

Trong IDE:

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

4

Trong .Net bạn có thể sử dụng

System.IO.Directory.GetCurrentDirectory

để lấy thư mục làm việc hiện tại của ứng dụng và trong VB.NET cụ thể bạn có thể sử dụng

My.Application.Info.DirectoryPath

để lấy thư mục của exe.


3

Delphi

Trong các ứng dụng Windows:

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

Trong các ứng dụng bảng điều khiển:

Không phụ thuộc vào ngôn ngữ, tham số dòng lệnh đầu tiên là tên thực thi đủ điều kiện:

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

3


Môi trường kiểu Libc Trong * nix (cũng là Cygwin trong Windows):

  #include <unistd.h>

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

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

   char *get_current_dir_name(void);

Xem trang người đàn ông


2

Unix

Trong unix, người ta có thể tìm thấy đường dẫn đến tệp thực thi đã được bắt đầu bằng cách sử dụng các biến môi trường. Nó không nhất thiết phải là một đường dẫn tuyệt đối, vì vậy bạn sẽ cần kết hợp thư mục làm việc hiện tại (trong shell pwd:) và / hoặc biến PATH với giá trị của phần tử thứ 0 của môi trường.

Tuy nhiên, giá trị bị giới hạn trong unix, ví dụ như tệp thực thi có thể được gọi thông qua một liên kết tượng trưng và chỉ liên kết ban đầu được sử dụng cho biến môi trường. Nói chung, các ứng dụng trên unix không mạnh mẽ lắm nếu chúng sử dụng nó cho bất kỳ điều thú vị nào (chẳng hạn như tải tài nguyên). Trên unix, người ta thường sử dụng các vị trí được mã hóa cứng cho mọi thứ, ví dụ một tệp cấu hình trong /etcđó các vị trí tài nguyên được chỉ định.



2

Trong 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

trong Android của nó

getApplicationInfo().dataDir;

để lấy thẻ SD, tôi sử dụng

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

trong đó tệp sau được sử dụng để lưu trữ một loại tệp cụ thể (Âm thanh / Phim, v.v.). Bạn có hằng số cho các chuỗi này trong lớp Môi trường.

Về cơ bản, đối với bất kỳ điều gì liên quan đến ứng dụng, hãy sử dụng lớp ApplicationInfo và bất kỳ điều gì liên quan đến dữ liệu trong thẻ SD / Thư mục bên ngoài bằng cách sử dụng lớp Môi trường.

Tài liệu: ApplicationInfo , Môi trường


2

Trong Tcl

Đường dẫn của tập lệnh hiện tại:

set path [info script]

Đường dẫn trình bao Tcl:

set path [info nameofexecutable]

Nếu bạn cần thư mục của bất kỳ thư mục nào trong số này, hãy thực hiện:

set dir [file dirname $path]

Nhận thư mục hiện tại (đang làm việc):

set dir [pwd]

2

Java:

Trên tất cả các hệ thống (Windows, Linux, Mac OS X) chỉ hoạt động với tôi:

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

Điều này ném NPE nếu ứng dụng đang chạy trong tệp JAR.
user207421 14/12/16

1

trong Ruby , đoạn mã sau trả về đường dẫn của tệp nguồn hiện tại:

path = File.dirname(__FILE__)

1

Trong CFML có hai chức năng để truy cập đường dẫn của tập lệnh:

getBaseTemplatePath()
getCurrentTemplatePath()

Gọi getBaseTemplatePath trả về đường dẫn của tập lệnh 'cơ sở' - tức là đường dẫn được máy chủ web yêu cầu.
Gọi getCurrentTemplatePath trả về đường dẫn của tập lệnh hiện tại - tức là tập lệnh hiện đang thực thi.

Cả hai đường dẫn đều tuyệt đối và chứa đầy đủ thư mục + tên tệp của tập lệnh.

Để chỉ xác định thư mục, hãy sử dụng hàm getDirectoryFromPath( ... )trên kết quả.

Vì vậy, để xác định vị trí thư mục của một ứng dụng, bạn có thể làm:

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

Bên trong onApplicationStartsự kiện choApplication.cfc



Để xác định đường dẫn nơi máy chủ ứng dụng đang chạy công cụ CFML của bạn, bạn có thể truy cập các lệnh shell với cfexecute, vì vậy (lưu ý các thảo luận ở trên về pwd / etc) bạn có thể làm:

Unix:

<cfexecute name="pwd"/>

cho Windows, tạo một pwd.batvăn bản có chứa @cd, sau đó:

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

(Sử dụng variablethuộc tính of cfexecuteđể lưu trữ giá trị thay vì xuất ra màn hình.)


1

Trong cmd (trình bao dòng lệnh của Microsoft)

Bạn có thể lấy tên của tập lệnh với% * (có thể liên quan đến pwd)

Đây là thư mục của script:

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

Nếu bạn tìm thấy bất kỳ lỗi nào, bạn sẽ làm được. Sau đó, vui lòng sửa chữa hoặc nhận xét.


1

Tôi đã phát hành https://github.com/gpakosz/whereami giải quyết vấn đề trong C và cung cấp cho bạn:

  • đường dẫn đến tệp thực thi hiện tại
  • đường dẫn đến mô-đun hiện tại (khác với đường dẫn đến tệp thực thi khi gọi từ thư viện được chia sẻ).

Nó sử dụng GetModuleFileNameWtrên Windows, phân tích cú pháp /proc/self/mapstrên Linux và Android và sử dụng _NSGetExecutablePathhoặc dladdrtrên Mac và iOS.


0

Lưu ý trả lời "20 ở trên chỉ liên quan đến Mac OSX: Nếu tệp thực thi JAR được chuyển đổi thành" ứng dụng "thông qua OSX JAR BUNDLER, thì hàm getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (); sẽ KHÔNG trả về thư mục hiện tại của ứng dụng, nhưng sẽ thêm cấu trúc thư mục nội bộ của ứng dụng vào phản hồi. Cấu trúc nội bộ này của ứng dụng là / theCurrentFolderWhereTheAppReside / Contents / Resources / Java / yourfile

Có lẽ đây là một lỗi nhỏ trong Java. Dù sao, người ta phải sử dụng phương pháp một hoặc hai để có câu trả lời chính xác và cả hai sẽ cung cấp câu trả lời chính xác ngay cả khi ứng dụng được khởi động, ví dụ: thông qua một phím tắt nằm trong một thư mục khác hoặc trên màn hình.

carl

SoundPimp.com

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.