Как получить расширение файла в Java?
просто чтобы быть ясным, я не ищу тип MIME.
Допустим, у меня есть следующие вводные: /path/to/file/foo.txt
Я хотел бы способ разбить этот вход, в частности, на .txt расширение. Есть ли встроенный способ сделать это в Java? Я хотел бы избежать написания собственного парсера.
27 ответов:
в этом случае использовать FilenameUtils.getExtension С Apache Commons IO
вот пример его использования (вы можете указать либо полный путь, либо просто имя файла):
String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt" String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe"
вам действительно нужен "парсер" для этого?
String extension = ""; int i = fileName.lastIndexOf('.'); if (i > 0) { extension = fileName.substring(i+1); }предполагая, что вы имеете дело с простыми именами файлов Windows, а не с чем-то вроде
archive.tar.gz.кстати, в случае, если каталог может иметь '.', но само имя файла не (как
/path/to.a/file), вы можете сделатьString extension = ""; int i = fileName.lastIndexOf('.'); int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\')); if (i > p) { extension = fileName.substring(i+1); }
private String getFileExtension(File file) { String name = file.getName(); int lastIndexOf = name.lastIndexOf("."); if (lastIndexOf == -1) { return ""; // empty extension } return name.substring(lastIndexOf); }
если вы используете гуавы библиотека, вы можете прибегнуть к
Filesслужебный класс. Он имеет определенный метод,getFileExtension(). Например:String path = "c:/path/to/file/foo.txt"; String ext = Files.getFileExtension(path); System.out.println(ext); //prints txtкроме того, вы также можете получить имя файла с аналогичной функцией,getNameWithoutExtension ():
String filename = Files.getNameWithoutExtension(path); System.out.println(filename); //prints foo
Если на Android, вы можете использовать это:
String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
чтобы учесть имена файлов без символов до точка, вы должны использовать это небольшое изменение принятого ответа:
String extension = ""; int i = fileName.lastIndexOf('.'); if (i >= 0) { extension = fileName.substring(i+1); }
"file.doc" => "doc" "file.doc.gz" => "gz" ".doc" => "doc"
мой грязный и может мельчайший с помощью строку.заменяет:
.replaceAll("^.*\.(.*)$", "")обратите внимание, что первый
*жаден, поэтому он будет захватывать большинство возможных символов, насколько это возможно, а затем останется только последняя точка и расширение файла.
Это проверенный метод
public static String getExtension(String fileName) { char ch; int len; if(fileName==null || (len = fileName.length())==0 || (ch = fileName.charAt(len-1))=='/' || ch=='\' || //in the case of a directory ch=='.' ) //in the case of . or .. return ""; int dotInd = fileName.lastIndexOf('.'), sepInd = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\')); if( dotInd<=sepInd ) return ""; else return fileName.substring(dotInd+1).toLowerCase(); }и тестовый пример:
@Test public void testGetExtension() { assertEquals("", getExtension("C")); assertEquals("ext", getExtension("C.ext")); assertEquals("ext", getExtension("A/B/C.ext")); assertEquals("", getExtension("A/B/C.ext/")); assertEquals("", getExtension("A/B/C.ext/..")); assertEquals("bin", getExtension("A/B/C.bin")); assertEquals("hidden", getExtension(".hidden")); assertEquals("dsstore", getExtension("/user/home/.dsstore")); assertEquals("", getExtension(".strange.")); assertEquals("3", getExtension("1.2.3")); assertEquals("exe", getExtension("C:\Program Files (x86)\java\bin\javaw.exe")); }
Как насчет (С помощью Java 1.5 RegEx):
String[] split = fullFileName.split("\."); String ext = split[split.length - 1];
Если вы планируете использовать Apache commons-io, и просто хотите проверить расширение файла, а затем выполнить некоторую операцию, вы можете использовать этой,вот фрагмент:
if(FilenameUtils.isExtension(file.getName(),"java")) { someoperation(); }
Как видно из всех других ответов, нет адекватной "встроенной" функции. Это безопасный и простой метод.
String getFileExtension(File file) { if (file == null) { return ""; } String name = file.getName(); int i = name.lastIndexOf('.'); String ext = i > 0 ? name.substring(i + 1) : ""; return ext; }
Как насчет JFileChooser? Это не так просто, как вам нужно будет разобрать его конечный результат...
JFileChooser filechooser = new JFileChooser(); File file = new File("your.txt"); System.out.println("the extension type:"+filechooser.getTypeDescription(file));который является типом MIME...
ОК...Я забыл, что вы не хотите знать его тип мима.
интересный код в следующей ссылке: http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html
/* * Get the extension of a file. */ public static String getExtension(File f) { String ext = null; String s = f.getName(); int i = s.lastIndexOf('.'); if (i > 0 && i < s.length() - 1) { ext = s.substring(i+1).toLowerCase(); } return ext; }
вот метод, который обрабатывает
.tar.gzправильно, даже в пути с точками в именах каталогов:private static final String getExtension(final String filename) { if (filename == null) return null; final String afterLastSlash = filename.substring(filename.lastIndexOf('/') + 1); final int afterLastBackslash = afterLastSlash.lastIndexOf('\') + 1; final int dotIndex = afterLastSlash.indexOf('.', afterLastBackslash); return (dotIndex == -1) ? "" : afterLastSlash.substring(dotIndex + 1); }
afterLastSlashсоздается, чтобы сделать поискafterLastBackslashбыстрее, так как ему не придется искать всю строку, если в ней есть некоторые косые черты.The
char[]внутри оригинальныйStringиспользуется повторно, не добавляя туда мусора, и JVM, вероятно, заметит этоafterLastSlashэто сразу мусор, чтобы положить его в стек вместо куча.
а вот версия с дополнительным в качестве возвращаемого значения (потому что вы не можете быть уверены, что файл имеет расширение)... также проверяется вменяемость...
import java.io.File; import java.util.Optional; public class GetFileExtensionTool { public static Optional<String> getFileExtension(File file) { if (file == null) { throw new NullPointerException("file argument was null"); } if (!file.isFile()) { throw new IllegalArgumentException("getFileExtension(File file)" + " called on File object that wasn't an actual file" + " (perhaps a directory or device?). file had path: " + file.getAbsolutePath()); } String fileName = file.getName(); int i = fileName.lastIndexOf('.'); if (i > 0) { return Optional.of(fileName.substring(i + 1)); } else { return Optional.empty(); } } }
// Modified from EboMike's answer String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));
здесь я сделал небольшой метод (однако не настолько безопасный и не проверяющий на многие ошибки), но если это только вы программируете общую java-программу, этого более чем достаточно, чтобы найти тип файла. Это не работает для сложных типов файлов, но они обычно не используются так много.
public static String getFileType(String path){ String fileType = null; fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase(); return fileType; }
получение расширения файла из имени файла
/** * The extension separator character. */ private static final char EXTENSION_SEPARATOR = '.'; /** * The Unix separator character. */ private static final char UNIX_SEPARATOR = '/'; /** * The Windows separator character. */ private static final char WINDOWS_SEPARATOR = '\'; /** * The system separator character. */ private static final char SYSTEM_SEPARATOR = File.separatorChar; /** * Gets the extension of a filename. * <p> * This method returns the textual part of the filename after the last dot. * There must be no directory separator after the dot. * <pre> * foo.txt --> "txt" * a/b/c.jpg --> "jpg" * a/b.txt/c --> "" * a/b/c --> "" * </pre> * <p> * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to retrieve the extension of. * @return the extension of the file or an empty string if none exists. */ public static String getExtension(String filename) { if (filename == null) { return null; } int index = indexOfExtension(filename); if (index == -1) { return ""; } else { return filename.substring(index + 1); } } /** * Returns the index of the last extension separator character, which is a dot. * <p> * This method also checks that there is no directory separator after the last dot. * To do this it uses {@link #indexOfLastSeparator(String)} which will * handle a file in either Unix or Windows format. * <p> * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to find the last path separator in, null returns -1 * @return the index of the last separator character, or -1 if there * is no such character */ public static int indexOfExtension(String filename) { if (filename == null) { return -1; } int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR); int lastSeparator = indexOfLastSeparator(filename); return (lastSeparator > extensionPos ? -1 : extensionPos); } /** * Returns the index of the last directory separator character. * <p> * This method will handle a file in either Unix or Windows format. * The position of the last forward or backslash is returned. * <p> * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to find the last path separator in, null returns -1 * @return the index of the last separator character, or -1 if there * is no such character */ public static int indexOfLastSeparator(String filename) { if (filename == null) { return -1; } int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); return Math.max(lastUnixPos, lastWindowsPos); }кредиты
- скопировано из класса Apache FileNameUtils - http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.3.2/org/apache/commons/io/FilenameUtils.java#FilenameUtils.getExtension%28java.lang.String%29
как о регулярное выражение версия:
static final Pattern PATTERN = Pattern.compile("(.*)\.(.*)"); Matcher m = PATTERN.matcher(path); if (m.find()) { System.out.println("File path/name: " + m.group(1)); System.out.println("Extention: " + m.group(2)); }или с нулевым расширением поддерживается:
static final Pattern PATTERN = Pattern.compile("((.*\" + File.separator + ")?(.*)(\.(.*)))|(.*\" + File.separator + ")?(.*)"); class Separated { String path, name, ext; } Separated parsePath(String path) { Separated res = new Separated(); Matcher m = PATTERN.matcher(path); if (m.find()) { if (m.group(1) != null) { res.path = m.group(2); res.name = m.group(3); res.ext = m.group(5); } else { res.path = m.group(6); res.name = m.group(7); } } return res; } Separated sp = parsePath("/root/docs/readme.txt"); System.out.println("path: " + sp.path); System.out.println("name: " + sp.name); System.out.println("Extention: " + sp.ext);результат для *nix:
путь: / root / docs/
название: ридми
Расширение: txtдля windows, parsePath("c:\windows\readme.txt"):
путь:\c:\windows
название: ридми
Расширение: txt
без использования какой-либо библиотеки, вы можете использовать строковый метод split следующим образом :
String[] splits = fileNames.get(i).split("\."); String extension = ""; if(splits.length >= 2) { extension = splits[splits.length-1]; }
path = "/Users/test/test.txt" extension = path.substring(path.lastIndexOf("."), path.length());возвращение ".txt"
Если вы хотите только "txt", сделайте
path.lastIndexOf(".") + 1
просто альтернатива на основе регулярных выражений. Не так быстро, не так хорошо.
Pattern pattern = Pattern.compile("\.([^.]*)$"); Matcher matcher = pattern.matcher(fileName); if (matcher.find()) { String ext = matcher.group(1); }
этот конкретный вопрос дает мне много проблем, то я нашел очень простое решение для этой проблемы, которую я публикую здесь.
file.getName().toLowerCase().endsWith(".txt");вот и все.
Я нашел лучший способ найти расширение, смешивая все выше ответы
public static String getFileExtension(String fileLink) { String extension; Uri uri = Uri.parse(fileLink); String scheme = uri.getScheme(); if (scheme != null && scheme.equals(ContentResolver.SCHEME_CONTENT)) { MimeTypeMap mime = MimeTypeMap.getSingleton(); extension = mime.getExtensionFromMimeType(CoreApp.getInstance().getContentResolver().getType(uri)); } else { extension = MimeTypeMap.getFileExtensionFromUrl(fileLink); } return extension; } public static String getMimeType(String fileLink) { String type = CoreApp.getInstance().getContentResolver().getType(Uri.parse(fileLink)); if (!TextUtils.isEmpty(type)) return type; MimeTypeMap mime = MimeTypeMap.getSingleton(); return mime.getMimeTypeFromExtension(FileChooserUtil.getFileExtension(fileLink)); }
попробуйте это.
String[] extension = "adadad.adad.adnandad.jpg".split("\.(?=[^\.]+$)"); // ['adadad.adad.adnandad','jpg'] extension[1] // jpg
@Test public void getFileExtension(String fileName){ String extension = null; List<String> list = new ArrayList<>(); do{ extension = FilenameUtils.getExtension(fileName); if(extension==null){ break; } if(!extension.isEmpty()){ list.add("."+extension); } fileName = FilenameUtils.getBaseName(fileName); }while (!extension.isEmpty()); Collections.reverse(list); System.out.println(list.toString()); }
Java имеет встроенный способ борьбы с этим, в java.НИО.файл.Файлы класса, это может работать для ваших нужд:
File f = new File("/path/to/file/foo.txt"); String ext = Files.probeContentType(f.toPath()); if(ext.equalsIgnoreCase("txt")) do whatever;обратите внимание, что этот статический метод использует спецификации найти здесь чтобы получить "тип контента", который может варьироваться.
Comments