Как получить имя файла без расширения в Java?


Ответы:


429

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

import org.apache.commons.io.FilenameUtils;
String fileNameWithOutExt = FilenameUtils.removeExtension(fileNameWithExt);

61
Вы также можете использовать FilenameUtils.getBasename для перехода от строки пути к имени файла без расширения.
— Ян Дуркан

2
Самым простым является, конечно, запуск maven :-) В противном случае см .: commons.apache.org/io
— Ульф Линдбек

8
Для тех, кто предпочитает гуаву, он тоже может это сделать . (В настоящее время я лично не очень
— рад

3
Хотя Guava и Commons-IO могут предложить немного больше, вы будете удивлены тем, сколько удобных методов уже включено в JDK 7 с java.nio.file.Filesи Path- таких как разрешение базовых каталогов, копирование / перемещение файлов в одну строку, получение только имени файла и т. д.
— Дон Чидл

3
@Lan Durkan в настоящее время FilenameUtils.getBaseName с большой буквы N
— медленно Гарри

153

Самый простой способ - использовать регулярное выражение.

fileNameWithOutExt = "test.xml".replaceFirst("[.][^.]+$", "");

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

public void testRegex() {
    assertEquals("test", "test.xml".replaceFirst("[.][^.]+$", ""));
    assertEquals("test.2", "test.2.xml".replaceFirst("[.][^.]+$", ""));
}

11
Regex не так прост в использовании, как приведенное выше решение для библиотеки. Это работает, но смотреть на код (без необходимости интерпретировать REGEX) не очевидно, что он делает.
— Густаво Литовский

5
@GustavoLitovsky Android не поставляется в комплекте org.apache.commons. Насколько я знаю, это единственный способ сделать это в Android.
— Лиам Джордж Бетсворт

1
/ * следующее регулярное выражение также удаляет путь * / "/the/path/name.extension".replaceAll(".*[\\\\]]\\\[^\\.]*$", "") ;
— Даггетт

1
Я бы добавил косые черты ко второму классу персонажей, чтобы быть уверенным, что вас не запутает путь, подобный «/foo/bar.x/baz»
— chrisinmtown

53

Смотрите следующую тестовую программу:

public class javatemp {
    static String stripExtension (String str) {
        // Handle null case specially.

        if (str == null) return null;

        // Get position of last '.'.

        int pos = str.lastIndexOf(".");

        // If there wasn't any '.' just return the string as is.

        if (pos == -1) return str;

        // Otherwise return the string, up to the dot.

        return str.substring(0, pos);
    }

    public static void main(String[] args) {
        System.out.println ("test.xml   -> " + stripExtension ("test.xml"));
        System.out.println ("test.2.xml -> " + stripExtension ("test.2.xml"));
        System.out.println ("test       -> " + stripExtension ("test"));
        System.out.println ("test.      -> " + stripExtension ("test."));
    }
}

какие выводы:

test.xml   -> test
test.2.xml -> test.2
test       -> test
test.      -> test

Какое расширение foo.tar.gz? Я понимаю, почему это .tar.gzбыло бы то, что вы хотели бы.
— tchrist

5
@tchrist, foo.tar.gzэто версия gzip, foo.tarтак что вы также можете утверждать, что это gzбыло расширение. Все сводится к тому, как вы определяете расширение.
— paxdiablo

2
что делать с файлами вроде .gitignore?
— Михаил Нестеренко

Как вы знаете, имя класса в Java никогда не должно начинаться с маленькой буквы!
— AnujKu

7
Если бы это было правилом, язык обеспечил бы его соблюдение. Поскольку это не так, это руководство, как бы сильно оно ни предлагалось. В любом случае, это совершенно не имеет отношения к вопросу и ответу.
— paxdiablo

47

Вот порядок консолидированного списка по моим предпочтениям.

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

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

Использование Google Guava (если вы уже используете его)

import com.google.common.io.Files;
String fileNameWithOutExt = Files.getNameWithoutExtension(fileName);

Или используя Core Java

1)

String fileName = file.getName();
int pos = fileName.lastIndexOf(".");
if (pos > 0 && pos < (fileName.length() - 1)) { // If '.' is not the first or last character.
    fileName = fileName.substring(0, pos);
}

2)

if (fileName.indexOf(".") > 0) {
   return fileName.substring(0, fileName.lastIndexOf("."));
} else {
   return fileName;
}

3)

private static final Pattern ext = Pattern.compile("(?<=.)\\.[^.]+$");

public static String getFileNameWithoutExtension(File file) {
    return ext.matcher(file.getName()).replaceAll("");
}

Liferay API

import com.liferay.portal.kernel.util.FileUtil; 
String fileName = FileUtil.stripExtension(file.getName());

42

Если ваш проект использует Guava (14.0 или новее), вы можете пойти с Files.getNameWithoutExtension().

(По сути, то же самое, что и в FilenameUtils.removeExtension()Apache Commons IO, как следует из ответа, получившего наибольшее количество голосов . Просто хотел бы отметить, что Guava делает то же самое. Лично я не хотел добавлять зависимость к Commons, что, по моему мнению, является чем-то вроде реликта) только из-за этого.)


2
на самом деле это больше похоже наFilenameUtils.getBaseName()
— Angelo.Hannes

на самом деле guava - такая нестабильная библиотека, что я просто избегаю использовать ее везде, где могу. предпочитаю стабильную реликвию, чем эксперименты Гугеля
— Слава

8

Ниже приведена ссылка на https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/util/FileUtil.java.

/**
 * Gets the base name, without extension, of given file name.
 * <p/>
 * e.g. getBaseName("file.txt") will return "file"
 *
 * @param fileName
 * @return the base name
 */
public static String getBaseName(String fileName) {
    int index = fileName.lastIndexOf('.');
    if (index == -1) {
        return fileName;
    } else {
        return fileName.substring(0, index);
    }
}

1
Хорошая информация, но пользователи должны знать о таких случаях, как ".htaccess", где этот метод будет возвращать "".
— Маркус Шульте

6

Если вам не нравится импортировать полный apache.commons, я извлек ту же функциональность:

public class StringUtils {
    public static String getBaseName(String filename) {
        return removeExtension(getName(filename));
    }

    public static int indexOfLastSeparator(String filename) {
        if(filename == null) {
            return -1;
        } else {
            int lastUnixPos = filename.lastIndexOf(47);
            int lastWindowsPos = filename.lastIndexOf(92);
            return Math.max(lastUnixPos, lastWindowsPos);
        }
    }

    public static String getName(String filename) {
        if(filename == null) {
            return null;
        } else {
            int index = indexOfLastSeparator(filename);
            return filename.substring(index + 1);
        }
    }

    public static String removeExtension(String filename) {
        if(filename == null) {
            return null;
        } else {
            int index = indexOfExtension(filename);
            return index == -1?filename:filename.substring(0, index);
        }
    }

    public static int indexOfExtension(String filename) {
        if(filename == null) {
            return -1;
        } else {
            int extensionPos = filename.lastIndexOf(46);
            int lastSeparator = indexOfLastSeparator(filename);
            return lastSeparator > extensionPos?-1:extensionPos;
        }
    }
}

4

Хотя я очень верю в повторное использование библиотек, JAR org.apache.commons.io имеет размер 174 КБ, что заметно для мобильного приложения.

Если вы скачаете исходный код и взгляните на их класс FilenameUtils, вы увидите, что есть много дополнительных утилит, и они справляются с путями Windows и Unix, что прекрасно.

Однако, если вы просто хотите использовать несколько статических утилит для использования с путями в стиле Unix (с разделителем "/"), вы можете найти приведенный ниже код полезным.

removeExtensionМетод сохраняет остальную часть пути вместе с именем файла. Существует также аналогичное getExtension.

/**
 * Remove the file extension from a filename, that may include a path.
 * 
 * e.g. /path/to/myfile.jpg -> /path/to/myfile 
 */
public static String removeExtension(String filename) {
    if (filename == null) {
        return null;
    }

    int index = indexOfExtension(filename);

    if (index == -1) {
        return filename;
    } else {
        return filename.substring(0, index);
    }
}

/**
 * Return the file extension from a filename, including the "."
 * 
 * e.g. /path/to/myfile.jpg -> .jpg
 */
public static String getExtension(String filename) {
    if (filename == null) {
        return null;
    }

    int index = indexOfExtension(filename);

    if (index == -1) {
        return filename;
    } else {
        return filename.substring(index);
    }
}

private static final char EXTENSION_SEPARATOR = '.';
private static final char DIRECTORY_SEPARATOR = '/';

public static int indexOfExtension(String filename) {

    if (filename == null) {
        return -1;
    }

    // Check that no directory separator appears after the 
    // EXTENSION_SEPARATOR
    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);

    int lastDirSeparator = filename.lastIndexOf(DIRECTORY_SEPARATOR);

    if (lastDirSeparator > extensionPos) {
        LogIt.w(FileSystemUtil.class, "A directory separator appears after the file extension, assuming there is no file extension");
        return -1;
    }

    return extensionPos;
}

1
public static String getFileExtension(String fileName) {
        if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null;
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    public static String getBaseFileName(String fileName) {
        if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null;
        return fileName.substring(0,fileName.lastIndexOf("."));
    }

1

Простейший способ получить имя из относительного или полного пути - использовать

import org.apache.commons.io.FilenameUtils; FilenameUtils.getBaseName(definitionFilePath)


0

Вы можете разделить его на "." а в индексе 0 - имя файла, а в 1 - расширение, но я бы предпочел лучшее решение с FileNameUtils от apache.commons-io, как это было упомянуто в первой статье. Это не должно быть удалено, но достаточно:

String fileName = FilenameUtils.getBaseName("test.xml");


0

Используйте FilenameUtils.removeExtensionот Apache Commons IO

Пример:

Вы можете указать полный путь или только имя файла .

String myString1 = FilenameUtils.removeExtension("helloworld.exe"); // returns "helloworld"
String myString2 = FilenameUtils.removeExtension("/home/abc/yey.xls"); // returns "yey"

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


Это уже в принятом ответе, какой смысл в этом посте?
— Том


0

Для простоты используйте метод Java String.replaceAll () следующим образом:

String fileNameWithExt = "test.xml";
String fileNameWithoutExt
   = fileNameWithExt.replaceAll( "^.*?(([^/\\\\\\.]+))\\.[^\\.]+$", "$1" );

Это также работает, когда fileNameWithExt включает полный путь.


0

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

File filename = new File('test.txt'); File.getName().split("[.]");

поэтому split[0]вернет «test» и split [1] вернет «txt»


-3

Попробуйте код ниже. Использование основных функций Java. Он заботится о Strings с расширением и без расширения (без '.'символа). Случай множественного числа '.'также покрыт.

String str = "filename.xml";
if (!str.contains(".")) 
    System.out.println("File Name=" + str); 
else {
    str = str.substring(0, str.lastIndexOf("."));
    // Because extension is always after the last '.'
    System.out.println("File Name=" + str);
}

Вы можете адаптировать его для работы со nullстроками.


1
Это довольно плохая практика, чтобы реализовать такую ​​функциональность самостоятельно. На первый взгляд задача кажется предельно очевидной , но на практике вы столкнетесь с множеством исключительных ситуаций (например, нет .имени файла, или файл является резервной копией и имеет имя типа document.docx.backupи т. Д.). Гораздо надежнее использовать внешнюю библиотеку, которая решает все эти исключительные ситуации для вас.
— ivstas

1
С другой стороны, добавление многих библиотек в ваш проект сделает его больше. Такие простые вещи, как это можно сделать сами.
— Николас Тайлер

1
Никоим образом вы не должны делать это самостоятельно. Это сложно: файлы без расширения, но. в пути, пути ftp, косые черты в Windows и Unix, символические ссылки и т. д. Вы, безусловно, потерпите неудачу, и, пытаясь получить немного памяти, вы получите большую нестабильность. Как минимум, скопируйте источники установленного кода, если лицензии позволяют это.
— Джонатан Наппи

Этот код выглядит как код от Амит Мишры, за исключением того пугающего 'if (! Str.contains ("."))'
— Broken_Window

завершится с ошибкой в ​​следующем случае "/someFolder/some.other.folder/someFileWithoutExtention". Первое, что пришло в голову через 2 секунды ... Я уверен, что смогу придумать кучу других примеров.
— Ньютопия
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.