Как получить реальный путь к Java-приложению во время выполнения?

Я создаю приложение Java, где я использую log4j. Я дал абсолютный путь к файлу конфигурации log4j, а также абсолютный путь к созданному файлу журнала (где генерируется этот файл журнала). Я могу получить абсолютный путь веб-приложения Java во время выполнения через:

String prefix =  getServletContext().getRealPath("/");

но что мы можем использовать в контексте обычного Java-приложения?

15 ответов

Решение

Пытаться;

String path = new File(".").getCanonicalPath();

Не понятно, о чем ты просишь. Я не знаю, что "в отношении веб-приложения, которое мы используем" означает, что getServletContext().getRealPath() не ответ, но:

  • Текущий рабочий каталог текущего пользователя задается System.getProperty("user.dir")
  • Домашний каталог текущего пользователя задается System.getProperty("user.home")
  • Расположение файла JAR, из которого был загружен текущий класс, определяется как this.getClass().getProtectionDomain().getCodeSource().getLocation(),

А как насчет использования this.getClass().getProtectionDomain().getCodeSource().getLocation()?

Поскольку путь приложения JAR и приложение, запущенное изнутри IDE отличается, я написал следующий код, чтобы последовательно возвращать правильный текущий каталог:

import java.io.File;
import java.net.URISyntaxException;

public class ProgramDirectoryUtilities
{
    private static String getJarName()
    {
        return new File(ProgramDirectoryUtilities.class.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath())
                .getName();
    }

    private static boolean runningFromJAR()
    {
        String jarName = getJarName();
        return jarName.contains(".jar");
    }

    public static String getProgramDirectory()
    {
        if (runningFromJAR())
        {
            return getCurrentJARDirectory();
        } else
        {
            return getCurrentProjectDirectory();
        }
    }

    private static String getCurrentProjectDirectory()
    {
        return new File("").getAbsolutePath();
    }

    private static String getCurrentJARDirectory()
    {
        try
        {
            return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent();
        } catch (URISyntaxException exception)
        {
            exception.printStackTrace();
        }

        return null;
    }
}

Просто позвони getProgramDirectory() и ты должен быть хорошим в любом случае.

Если вы говорите о веб-приложении, вы должны использовать getRealPath из ServletContext объект.

Пример:

public class MyServlet extends Servlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) 
              throws ServletException, IOException{
         String webAppPath = getServletContext().getRealPath("/");
    }
}

Надеюсь это поможет.

new File(".").getAbsolutePath()

Я использую этот метод, чтобы получить полный путь к jar или exe.

File pto = new File(YourClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());

pto.getAbsolutePath());
/*****************************************************************************
     * return application path
     * @return
     *****************************************************************************/
    public static String getApplcatonPath(){
        CodeSource codeSource = MainApp.class.getProtectionDomain().getCodeSource();
        File rootPath = null;
        try {
            rootPath = new File(codeSource.getLocation().toURI().getPath());
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
        return rootPath.getParentFile().getPath();
    }//end of getApplcatonPath()

Лучше сохранять файлы в подкаталоге user.home, чем в любом месте приложения. может проживать.

Sun приложила немало усилий, чтобы обеспечить апплеты и приложения. запущенный с помощью Java Web Start не может определить приложения. реальный путь. Это изменение сломало много приложений. Я не удивлюсь, если изменения будут распространены на другие приложения.

Я думаю System.getProperty("java.class.path")а также System.getProperty("path.separator")схемы лучше. например:

      private final static String JAR_SUFFIX = ".jar";

public static String getJarRuntimePath(){
        String javaClassPath = System.getProperty("java.class.path");
        String pathSeparator = System.getProperty("path.separator");
        if(javaClassPath.contains(pathSeparator)){
            javaClassPath = filePath.substring(0,filePath.indexOf(pathSeparator));
        }else if (javaClassPath.endsWith(JAR_SUFFIX)) {
            javaClassPath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1);
        }
        File serverLocalConfig = new File(javaClassPath);
        return serverLocalConfig.getAbsolutePath();
}

Я думаю, что все упускают из виду ключевую проблему.

      String prefix =  getServletContext().getRealPath("/");

Экземпляр сервлета может находиться на одном из сколь угодно большого количества узлов и технически не требует файловой системы.

Например, в контейнерах Java EE приложение может быть загружено из базы данных или даже с сервера каталогов. Различные части приложения также могут работать на разных узлах. Доступ к миру за пределами приложения обеспечивается сервером приложения.

Используйте java.util.logging или Apache Commons Logging, если вам необходимо поддерживать совместимость с устаревшим log4j. Сообщите серверу приложений, куда должен идти файл журнала.

Если вы хотите получить реальный путь к веб-приложению Java, например Spring (Servlet), вы можете получить его из объекта контекста Servlet, который входит в ваш HttpServletRequest.

@GetMapping("/")
public String index(ModelMap m, HttpServletRequest request) {
    String realPath = request.getServletContext().getRealPath("/");
    System.out.println(realPath);
    return "index";
}

У меня есть файл cost.ini в корне пути к моему классу. Мой файл JAR называется "cost.jar".

Следующий код:

  • Если у нас есть файл JAR, берет каталог, в котором находится файл JAR.
  • Если у нас есть файлы *.class, берет каталог корня классов.

try {
    //JDK11: replace "UTF-8" with UTF_8 and remove try-catch
    String rootPath = decode(getSystemResource("cost.ini").getPath()
            .replaceAll("(cost\\.jar!/)?cost\\.ini$|^(file\\:)?/", ""), "UTF-8");
    showMessageDialog(null, rootPath, "rootpath", WARNING_MESSAGE);
} catch(UnsupportedEncodingException e) {}

Путь вернулся из .getPath() имеет формат:

  • В JAR: file:/C:/folder1/folder2/cost.jar!/cost.ini
  • В классе: /C:/folder1/folder2/cost.ini

    Каждое использование File, приводит к исключению, если приложение предоставлено в формате JAR.

  • Если вы хотите использовать этот ответ: /questions/14700905/kak-poluchit-realnyij-put-k-java-prilozheniyu-vo-vremya-vyipolneniya/14700919#14700919

    Вы должны добавить оператор импорта следующим образом:

    import java.io.File;

    в самом начале исходного кода Java.

    нравится этот ответ: /questions/14700905/kak-poluchit-realnyij-put-k-java-prilozheniyu-vo-vremya-vyipolneniya/14700927#14700927

    Выражение

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

    вы получите текущий рабочий каталог, связанный с выполнением JVM. Тем не менее, JVM предоставляет множество других полезных свойств через

    System.getProperty(propertyName); 
    

    интерфейс. Список этих свойств можно найти здесь.

    Это позволит вам ссылаться на каталог текущих пользователей, временный каталог и т. Д. Независимо от платформы.

    Другие вопросы по тегам