Как получить имя файла из строки, содержащей абсолютный путь к файлу?

237

Stringпеременная содержит имя файла C:\Hello\AnotherFolder\The File Name.PDF. Как получить только имя файла The File Name.PDFв виде строки?

Я планировал разделить строку, но это не оптимальное решение.

Шэрон Хоук
источник
со ссылкой на issetracker.google.com/issues/37131215 это было исправлено.
Prags

Ответы:

281

просто используйте File.getName ()

File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");
System.out.println(f.getName());

используя методы String :

  File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\")+1));
PermGenError
источник
Полезно. Спасибо.
Пуджа
Будьте осторожны с путями с "/" вместо "\"
golimar
278

Альтернативное использование Path(Java 7+):

Path p = Paths.get("C:\\Hello\\AnotherFolder\\The File Name.PDF");
String file = p.getFileName().toString();

Обратите внимание, что разделение строки \\зависит от платформы, поскольку разделитель файлов может отличаться. Path#getNameзаботится об этом вопросе для вас.

assylias
источник
1
Кто-нибудь делал сравнение производительности по различным методам в этом вопросе?
раздавить
@crush Я не думаю, что это Paths.getобращается к файловой системе, поэтому не стоит ожидать, что производительность будет существенно отличаться от подстроки / indexOf.
assylias
7
Почему это не существует на Android? странно.
Android-разработчик
12
Да, Path справляется с зависимой от платформы проблемой косой черты / обратной косой черты, но только в том случае, если путь к файлу идет с того же компьютера (или платформы). Подумайте об этом: вы загружаете файл, Internet Explorerи у него есть путь, "C:\\Hello\\AnotherFolder\\The File Name.PDF"но ваш код работает на Unix / Linux-машине, а затем p.getFileName()вернет весь путь, а не только The File Name.PDF.
nyxz 29.12.14
3
Звонить toString()так неловко.
PetroCliff
53

Использование FilenameUtilsв Apache Commons IO :

String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");
Биной ​​Бабу
источник
5
Я думаю, что этот может быть лучшим, потому что иногда вам может
понадобиться
Это лучше всего потому, что: легко читаемый, самый надежный, менее объектный кодер в коде +1
fl0w
32

Учитывая, что Stringвы спрашиваете о том,

C:\Hello\AnotherFolder\The File Name.PDF

нам нужно извлечь все после последнего разделителя, т.е. \, Это то, что нас интересует.

Ты можешь сделать

String fullPath = "C:\\Hello\\AnotherFolder\\The File Name.PDF";
int index = fullPath.lastIndexOf("\\");
String fileName = fullPath.substring(index + 1);

Это извлечет индекс последнего \в вашем Stringи извлечет все, что идет после него fileName.

Если у вас есть Stringдругой разделитель, настройте его, lastIndexOfчтобы использовать этот разделитель. (Есть даже перегрузка, которая принимает целое Stringкак разделитель.)

Я пропустил его в приведенном выше примере, но если вы не уверены, откуда он Stringили что он может содержать, вы захотите проверить, что он lastIndexOfвозвращает неотрицательное значение, потому что Javadoc заявляет, что он вернет

-1 если такого вхождения нет

Сотириос Делиманолис
источник
25

С 1.7

    Path p = Paths.get("c:\\temp\\1.txt");
    String fileName = p.getFileName().toString();
    String directory = p.getParent().toString();
max3d
источник
11

Вы можете использовать путь = C: \ Hello \ AnotherFolder \ TheFileName.PDF

String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());
Ракеш
источник
Вы должны использовать \\ вместо \
Anoop Chandrika HarisudhanNair
2
Вы не должны использовать какие-либо из них, поскольку это зависит от платформы. /на Unix и \`(AND THERE IS A BUG IN THE MARKDOWN PARSER HERE) on windows. You can't know. Use another solution like File` или Paths.
Автомат
3
Есть File.separatorтакже зависят от платформы? Или это сработает ... String strPath = path.substring(path.lastIndexOf(File.separator)+1, path.length());
Джонатан
File.separator и File.separatorChar оба являются "/" в версии JDK для UNIX / Linux / macOS и оба "\" в версии для Windows.
可 可 Джеки
2
File.separatorне всегда будет работать здесь, потому что в Windows имя файла может быть разделено либо либо, "/"либо "\\".
DodgyCodeException
10

Другие ответы не совсем работали для моего конкретного сценария, где я читаю пути, которые произошли от ОС, отличной от моей текущей. Чтобы уточнить, я сохраняю вложения электронной почты, сохраненные с платформы Windows на сервере Linux. Имя файла, возвращаемое из API JavaMail, выглядит как «C: \ temp \ hello.xls»

Решение, которое я выбрал:

String filenameWithPath = "C:\\temp\\hello.xls";
String[] tokens = filenameWithPath.split("[\\\\|/]");
String filename = tokens[tokens.length - 1];
javaPhobic
источник
3

Рассмотрим случай, когда Java является мультиплатформенным:

int lastPath = fileName.lastIndexOf(File.separator);
if (lastPath!=-1){
    fileName = fileName.substring(lastPath+1);
}
Алехандро Хдз
источник
1

Метод без какой-либо зависимости и заботится о .. , . и дубликаты разделителей.

public static String getFileName(String filePath) {
    if( filePath==null || filePath.length()==0 )
        return "";
    filePath = filePath.replaceAll("[/\\\\]+", "/");
    int len = filePath.length(),
        upCount = 0;
    while( len>0 ) {
        //remove trailing separator
        if( filePath.charAt(len-1)=='/' ) {
            len--;
            if( len==0 )
                return "";
        }
        int lastInd = filePath.lastIndexOf('/', len-1);
        String fileName = filePath.substring(lastInd+1, len);
        if( fileName.equals(".") ) {
            len--;
        }
        else if( fileName.equals("..") ) {
            len -= 2;
            upCount++;
        }
        else {
            if( upCount==0 )
                return fileName;
            upCount--;
            len -= fileName.length();
        }
    }
    return "";
}

Прецедент:

@Test
public void testGetFileName() {
    assertEquals("", getFileName("/"));
    assertEquals("", getFileName("////"));
    assertEquals("", getFileName("//C//.//../"));
    assertEquals("", getFileName("C//.//../"));
    assertEquals("C", getFileName("C"));
    assertEquals("C", getFileName("/C"));
    assertEquals("C", getFileName("/C/"));
    assertEquals("C", getFileName("//C//"));
    assertEquals("C", getFileName("/A/B/C/"));
    assertEquals("C", getFileName("/A/B/C"));
    assertEquals("C", getFileName("/C/./B/../"));
    assertEquals("C", getFileName("//C//./B//..///"));
    assertEquals("user", getFileName("/user/java/.."));
    assertEquals("C:", getFileName("C:"));
    assertEquals("C:", getFileName("/C:"));
    assertEquals("java", getFileName("C:\\Program Files (x86)\\java\\bin\\.."));
    assertEquals("C.ext", getFileName("/A/B/C.ext"));
    assertEquals("C.ext", getFileName("C.ext"));
}

Возможно, getFileName немного сбивает с толку, потому что он также возвращает имена каталогов. Возвращает имя файла или последний каталог в пути.

yavuzkavus
источник
0

извлечь имя файла с помощью регулярных выражений Java *.

public String extractFileName(String fullPathFile){
        try {
            Pattern regex = Pattern.compile("([^\\\\/:*?\"<>|\r\n]+$)");
            Matcher regexMatcher = regex.matcher(fullPathFile);
            if (regexMatcher.find()){
                return regexMatcher.group(1);
            }
        } catch (PatternSyntaxException ex) {
            LOG.info("extractFileName::pattern problem <"+fullPathFile+">",ex);
        }
        return fullPathFile;
    }
ХИК
источник
0

Вы можете использовать объект FileInfo, чтобы получить всю информацию о вашем файле.

    FileInfo f = new FileInfo(@"C:\Hello\AnotherFolder\The File Name.PDF");
    MessageBox.Show(f.Name);
    MessageBox.Show(f.FullName);
    MessageBox.Show(f.Extension );
    MessageBox.Show(f.DirectoryName);
Синий феникс
источник