Java File.toString или Path.toString с определенным разделителем путей

Я разрабатываю приложение Scala в Windows, и мне нужно вставить путь к файлу в HTML-шаблон. Я использую Java io и nio для работы с файлами и путями.

/* The paths actually come from the environment. */
val includesPath = Paths.get("foo\\inc")
val destinationPath = Paths.get("bar\\dest")

/* relativeIncludesPath.toString == "..\\foo\\inc", as expected */
val relativeIncludesPath = destinationPath.relativize(includesPath)

Проблема заключается в том, что вывод relativeIncludesPath.toString содержит обратные косые черты \ в качестве разделителей - потому что приложение работает в Windows - но поскольку путь должен быть вставлен в шаблон HTML, он должен содержать косые черты / вместо.

Так как я не мог найти ничего подобного file/path.toStringUsingSeparator('/') в документах, я в настоящее время помогаю себе с relativeIncludesPath.toString.replace('\\', '/'), который я нахожу довольно непривлекательным.

Вопрос: Нет ли лучшего способа, чем заменить?

Я также экспериментировал с Java URI, но он relativize неполный.

Ответ 1

Реализация интерфейса Пути в Windows хранит путь внутри себя как строку (по крайней мере, в OpenJDK) и просто возвращает это представление, когда Вызывается toString(). Это означает, что никакие вычисления не задействованы, и нет возможности "настроить" любой разделитель путей.

По этой причине я пришел к выводу, что ваше решение в настоящее время является лучшим вариантом для решения вашей проблемы.

Ответ 2

Я просто столкнулся с этой проблемой. Если у вас есть относительный путь, вы можете использовать тот факт, что Path является Iterable<Path> его элементов, следуя необязательному начальному корневому элементу, а затем может конкатенировать части самостоятельно с помощью косой черты. К сожалению, корневой элемент может содержать косые черты, например. в Windows вы получаете такие корневые элементы, как c:\ и \\foo\bar\ (для UNC-путей), поэтому кажется, что вам все равно придется заменять прямыми косыми чертами. Но вы могли бы сделать что-то вроде этого...

static public String pathToPortableString(Path p)
{
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    Path root = p.getRoot();
    if (root != null)
    {
        sb.append(root.toString().replace('\\','/'));
        /* root elements appear to contain their
         * own ending separator, so we don't set "first" to false
         */            
    }
    for (Path element : p)
    {
       if (first)
          first = false;
       else
          sb.append("/");
       sb.append(element.toString());
    }
    return sb.toString();        
}

и когда я тестирую его с помощью этого кода:

static public void doit(String rawpath)
{
    File f = new File(rawpath);
    Path p = f.toPath();
    System.out.println("Path: "+p.toString());
    System.out.println("      "+pathToPortableString(p));
}

static public void main(String[] args) {
    doit("\\\\quux\\foo\\bar\\baz.pdf");
    doit("c:\\foo\\bar\\baz.pdf");
    doit("\\foo\\bar\\baz.pdf");
    doit("foo\\bar\\baz.pdf");
    doit("bar\\baz.pdf");
    doit("bar\\");
    doit("bar");
}

Я получаю это:

Path: \\quux\foo\bar\baz.pdf
      //quux/foo/bar/baz.pdf
Path: c:\foo\bar\baz.pdf
      c:/foo/bar/baz.pdf
Path: \foo\bar\baz.pdf
      /foo/bar/baz.pdf
Path: foo\bar\baz.pdf
      foo/bar/baz.pdf
Path: bar\baz.pdf
      bar/baz.pdf
Path: bar
      bar
Path: bar
      bar

Текстовая подстановка обратной косой черты косой чертой, безусловно, проще, но я понятия не имею, сломает ли она какой-нибудь коварный край. (Может ли быть обратная косая черта в дорожках Unix?)

Ответ 3

Вы можете получить большинство свойств системы в Java. Взгляните на эту ссылку:

http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

Вы хотите:

Key: "file.separator"
Meaning: Character that separates components of a file path. This is "/" on UNIX and "\" on Windows.

String sep = System.getProperty("path.separator");