Если вы, как и я, предпочли бы использовать некоторый библиотечный код, в котором они, вероятно, подумали обо всех особых случаях, например, что произойдет, если вы передадите ноль или точки в пути, но не в имени файла, вы можете использовать следующее:
Хотя Guava и Commons-IO могут предложить немного больше, вы будете удивлены тем, сколько удобных методов уже включено в JDK 7 с java.nio.file.Filesи Path- таких как разрешение базовых каталогов, копирование / перемещение файлов в одну строку, получение только имени файла и т. д.
Дон Чидл
3
@Lan Durkan в настоящее время FilenameUtils.getBaseName с большой буквы N
медленно Гарри
153
Самый простой способ - использовать регулярное выражение.
Regex не так прост в использовании, как приведенное выше решение для библиотеки. Это работает, но смотреть на код (без необходимости интерпретировать REGEX) не очевидно, что он делает.
Густаво Литовский
5
@GustavoLitovsky Android не поставляется в комплекте org.apache.commons. Насколько я знаю, это единственный способ сделать это в Android.
Лиам Джордж Бетсворт
1
/ * следующее регулярное выражение также удаляет путь * / "/the/path/name.extension".replaceAll(".*[\\\\]]\\\[^\\.]*$", "") ;
Даггетт
1
Я бы добавил косые черты ко второму классу персонажей, чтобы быть уверенным, что вас не запутает путь, подобный «/foo/bar.x/baz»
chrisinmtown
53
Смотрите следующую тестовую программу:
publicclass javatemp {staticString stripExtension (String str){// Handle null case specially.if(str ==null)returnnull;// 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);}publicstaticvoid 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 (если вы уже используете его)
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);}
(По сути, то же самое, что и в FilenameUtils.removeExtension()Apache Commons IO, как следует из ответа, получившего наибольшее количество голосов . Просто хотел бы отметить, что Guava делает то же самое. Лично я не хотел добавлять зависимость к Commons, что, по моему мнению, является чем-то вроде реликта) только из-за этого.)
на самом деле это больше похоже наFilenameUtils.getBaseName()
Angelo.Hannes
на самом деле guava - такая нестабильная библиотека, что я просто избегаю использовать ее везде, где могу. предпочитаю стабильную реликвию, чем эксперименты Гугеля
/**
* 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
*/publicstaticString getBaseName(String fileName){int index = fileName.lastIndexOf('.');if(index ==-1){return fileName;}else{return fileName.substring(0, index);}}
Хотя я очень верю в повторное использование библиотек, 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
*/publicstaticString removeExtension(String filename){if(filename ==null){returnnull;}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
*/publicstaticString getExtension(String filename){if(filename ==null){returnnull;}int index = indexOfExtension(filename);if(index ==-1){return filename;}else{return filename.substring(index);}}privatestaticfinalchar EXTENSION_SEPARATOR ='.';privatestaticfinalchar DIRECTORY_SEPARATOR ='/';publicstaticint indexOfExtension(String filename){if(filename ==null){return-1;}// Check that no directory separator appears after the // EXTENSION_SEPARATORint 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;}
Вы можете разделить его на "." а в индексе 0 - имя файла, а в 1 - расширение, но я бы предпочел лучшее решение с FileNameUtils от apache.commons-io, как это было упомянуто в первой статье. Это не должно быть удалено, но достаточно:
Вы можете использовать функцию разделения Java, чтобы отделить имя файла от расширения, если вы уверены, что в имени файла есть только одна точка для расширения.
File filename = new File('test.txt');
File.getName().split("[.]");
поэтому split[0]вернет «test» и split [1] вернет «txt»
Попробуйте код ниже. Использование основных функций 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строками.
Это довольно плохая практика, чтобы реализовать такую функциональность самостоятельно. На первый взгляд задача кажется предельно очевидной , но на практике вы столкнетесь с множеством исключительных ситуаций (например, нет .имени файла, или файл является резервной копией и имеет имя типа document.docx.backupи т. Д.). Гораздо надежнее использовать внешнюю библиотеку, которая решает все эти исключительные ситуации для вас.
ivstas
1
С другой стороны, добавление многих библиотек в ваш проект сделает его больше. Такие простые вещи, как это можно сделать сами.
Николас Тайлер
1
Никоим образом вы не должны делать это самостоятельно. Это сложно: файлы без расширения, но. в пути, пути ftp, косые черты в Windows и Unix, символические ссылки и т. д. Вы, безусловно, потерпите неудачу, и, пытаясь получить немного памяти, вы получите большую нестабильность. Как минимум, скопируйте источники установленного кода, если лицензии позволяют это.
Джонатан Наппи
Этот код выглядит как код от Амит Мишры, за исключением того пугающего 'if (! Str.contains ("."))'
Broken_Window
завершится с ошибкой в следующем случае "/someFolder/some.other.folder/someFileWithoutExtention". Первое, что пришло в голову через 2 секунды ... Я уверен, что смогу придумать кучу других примеров.
Ответы:
Если вы, как и я, предпочли бы использовать некоторый библиотечный код, в котором они, вероятно, подумали обо всех особых случаях, например, что произойдет, если вы передадите ноль или точки в пути, но не в имени файла, вы можете использовать следующее:
источник
java.nio.file.Files
иPath
- таких как разрешение базовых каталогов, копирование / перемещение файлов в одну строку, получение только имени файла и т. д.Самый простой способ - использовать регулярное выражение.
Вышеупомянутое выражение удалит последнюю точку, за которой следует один или несколько символов. Вот базовый юнит-тест.
источник
org.apache.commons
. Насколько я знаю, это единственный способ сделать это в Android.Смотрите следующую тестовую программу:
какие выводы:
источник
foo.tar.gz
? Я понимаю, почему это.tar.gz
было бы то, что вы хотели бы.foo.tar.gz
это версия gzip,foo.tar
так что вы также можете утверждать, что этоgz
было расширение. Все сводится к тому, как вы определяете расширение..gitignore
?Вот порядок консолидированного списка по моим предпочтениям.
Использование Apache Commons
Использование Google Guava (если вы уже используете его)
Или используя Core Java
1)
2)
3)
Liferay API
источник
Если ваш проект использует Guava (14.0 или новее), вы можете пойти с
Files.getNameWithoutExtension()
.(По сути, то же самое, что и в
FilenameUtils.removeExtension()
Apache Commons IO, как следует из ответа, получившего наибольшее количество голосов . Просто хотел бы отметить, что Guava делает то же самое. Лично я не хотел добавлять зависимость к Commons, что, по моему мнению, является чем-то вроде реликта) только из-за этого.)источник
FilenameUtils.getBaseName()
Ниже приведена ссылка на https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/util/FileUtil.java.
источник
Если вам не нравится импортировать полный apache.commons, я извлек ту же функциональность:
источник
Хотя я очень верю в повторное использование библиотек, JAR org.apache.commons.io имеет размер 174 КБ, что заметно для мобильного приложения.
Если вы скачаете исходный код и взгляните на их класс FilenameUtils, вы увидите, что есть много дополнительных утилит, и они справляются с путями Windows и Unix, что прекрасно.
Однако, если вы просто хотите использовать несколько статических утилит для использования с путями в стиле Unix (с разделителем "/"), вы можете найти приведенный ниже код полезным.
removeExtension
Метод сохраняет остальную часть пути вместе с именем файла. Существует также аналогичноеgetExtension
.источник
источник
Простейший способ получить имя из относительного или полного пути - использовать
import org.apache.commons.io.FilenameUtils; FilenameUtils.getBaseName(definitionFilePath)
источник
Вы можете разделить его на "." а в индексе 0 - имя файла, а в 1 - расширение, но я бы предпочел лучшее решение с FileNameUtils от apache.commons-io, как это было упомянуто в первой статье. Это не должно быть удалено, но достаточно:
String fileName = FilenameUtils.getBaseName("test.xml");
источник
Используйте
FilenameUtils.removeExtension
от Apache Commons IOПример:
Вы можете указать полный путь или только имя файла .
Надеюсь это поможет ..
источник
Свободный путь:
источник
Для простоты используйте метод Java String.replaceAll () следующим образом:
Это также работает, когда fileNameWithExt включает полный путь.
источник
Вы можете использовать функцию разделения Java, чтобы отделить имя файла от расширения, если вы уверены, что в имени файла есть только одна точка для расширения.
File filename = new File('test.txt'); File.getName().split("[.]");
поэтому
split[0]
вернет «test» и split [1] вернет «txt»источник
Попробуйте код ниже. Использование основных функций Java. Он заботится о
String
s с расширением и без расширения (без'.'
символа). Случай множественного числа'.'
также покрыт.Вы можете адаптировать его для работы со
null
строками.источник
.
имени файла, или файл является резервной копией и имеет имя типаdocument.docx.backup
и т. Д.). Гораздо надежнее использовать внешнюю библиотеку, которая решает все эти исключительные ситуации для вас.