Java: разделение имени файла на базу и расширение

Есть ли лучший способ получить базовое имя и расширение файла, чем что-то вроде

File f = ...
String name = f.getName();
int dot = name.lastIndexOf('.');
String base = (dot == -1) ? name : name.substring(0, dot);
String extension = (dot == -1) ? "" : name.substring(dot+1);

Ответ 1

Я знаю, что другие упомянули String.split, но вот вариант, который дает только два токена (основание и расширение):

String[] tokens = fileName.split("\\.(?=[^\\.]+$)");

Например:

"test.cool.awesome.txt".split("\\.(?=[^\\.]+$)");

Урожайность:

["test.cool.awesome", "txt"]

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

Технически Режимеозно, этот метод называется позицией с нулевой шириной.


BTW, если вы хотите разделить путь и получить полное имя файла, включая, помимо прочего, расширение точки, используя путь с косой чертой,

    String[] tokens = dir.split(".+?/(?=[^/]+$)");

Например:

    String dir = "/foo/bar/bam/boozled"; 
    String[] tokens = dir.split(".+?/(?=[^/]+$)");
    // [ "/foo/bar/bam/" "boozled" ] 

Ответ 2

Старый вопрос, но я обычно использую это решение:

import org.apache.commons.io.FilenameUtils;

String fileName = "/abc/defg/file.txt";

String basename = FilenameUtils.getBaseName(fileName);
String extension = FilenameUtils.getExtension(fileName);
System.out.println(basename); // file
System.out.println(extension); // txt (NOT ".txt" !)

Ответ 3

Источник: http://www.java2s.com/Code/Java/File-Input-Output/Getextensionpathandfilename.htm

такой класс утилиты:

class Filename {
  private String fullPath;
  private char pathSeparator, extensionSeparator;

  public Filename(String str, char sep, char ext) {
    fullPath = str;
    pathSeparator = sep;
    extensionSeparator = ext;
  }

  public String extension() {
    int dot = fullPath.lastIndexOf(extensionSeparator);
    return fullPath.substring(dot + 1);
  }

  public String filename() { // gets filename without extension
    int dot = fullPath.lastIndexOf(extensionSeparator);
    int sep = fullPath.lastIndexOf(pathSeparator);
    return fullPath.substring(sep + 1, dot);
  }

  public String path() {
    int sep = fullPath.lastIndexOf(pathSeparator);
    return fullPath.substring(0, sep);
  }
}

использование:

public class FilenameDemo {
  public static void main(String[] args) {
    final String FPATH = "/home/mem/index.html";
    Filename myHomePage = new Filename(FPATH, '/', '.');
    System.out.println("Extension = " + myHomePage.extension());
    System.out.println("Filename = " + myHomePage.filename());
    System.out.println("Path = " + myHomePage.path());
  }
}

Ответ 4

Расширения файлов являются нарушенной концепцией

И не существует надежной функции для этого. Рассмотрим, например, это имя файла:

archive.tar.gz

Что такое расширение? Пользователи DOS предпочли бы имя archive.tgz. Иногда вы видите глупые приложения Windows, которые сначала распаковывают файл (получая файл .tar), а затем вам нужно открыть его снова, чтобы увидеть содержимое архива.

В этом случае более разумным понятием расширения файла было бы .tar.gz. Также используются "расширения" файлов .tar.bz2, .tar.xz, .tar.lz и .tar.lzma. Но как бы вы решили, делить ли на последнюю точку или на точку с предпоследней точкой?

Вместо этого используйте mime-типы.

Функция Java 7 Files.probeContentType, вероятно, будет намного надежнее определять типы файлов, чем доверять расширению файла. Практически весь мир Unix/Linux, а также ваш веб-браузер и смартфон уже делают это таким образом.

Ответ 5

http://docs.oracle.com/javase/6/docs/api/java/io/File.html#getName()

Из http://www.xinotes.org/notes/note/774/:

Java имеет встроенные функции для получения базового имени и dirname для заданного пути к файлу, но имена функций не так очевидны.

import java.io.File;

public class JavaFileDirNameBaseName {
    public static void main(String[] args) {
    File theFile = new File("../foo/bar/baz.txt");
    System.out.println("Dirname: " + theFile.getParent());
    System.out.println("Basename: " + theFile.getName());
    }
}

Ответ 6

Что не так с вашим кодом? Обернутый в аккуратный метод полезности. Прекрасно.

Что еще важнее, что использовать в качестве разделителя — первая или последняя точка. Первое плохо для имен файлов, таких как "setup-2.5.1.exe", последнее плохо для имен файлов с несколькими расширениями, такими как "mybundle.tar.gz".

Ответ 8

Возможно, вы могли бы использовать String # split

Чтобы ответить на ваш комментарий:

Я не уверен, может ли быть несколько. в имени файла, но независимо от того, даже если есть больше точек, вы можете использовать split. Рассмотрим, например, что:

String input = "boo.and.foo";

String[] result = input.split(".");

Это возвращает массив, содержащий:

{ "boo", "and", "foo" }

Итак, вы узнаете, что последний индекс в массиве - это расширение, а все остальные - база.