¿Cómo obtengo la extensión de archivo de un archivo en Java?

Para que quede claro, no estoy buscando el tipo MIME.

Digamos que tengo la siguiente entrada: /path/to/file/foo.txt

Me gustaría una forma de romper esta entrada, específicamente en .txt para la extensión. ¿Hay alguna forma de hacerlo en Java? Me gustaría evitar escribir mi propio analizador.

En este caso, use FilenameUtils.getExtension de Apache Commons IO

Aquí hay un ejemplo de cómo usarlo (puede especificar la ruta completa o solo el nombre del archivo):

 String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt" String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe" 

¿Realmente necesitas un “analizador” para esto?

 String extension = ""; int i = fileName.lastIndexOf('.'); if (i > 0) { extension = fileName.substring(i+1); } 

Suponiendo que se trata de nombres de archivo simples de Windows, no algo como archive.tar.gz .

Por cierto, para el caso de que un directorio pueda tener un ‘.’, Pero el nombre del archivo en sí no (como /path/to.a/file ), puede hacer

 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); } 

Si usa la biblioteca de Guava , puede recurrir a la clase de utilidad Files . Tiene un método específico, getFileExtension() . Por ejemplo:

 String path = "c:/path/to/file/foo.txt"; String ext = Files.getFileExtension(path); System.out.println(ext); //prints txt 

Además, también puede obtener el nombre de archivo con una función similar, getNameWithoutExtension () :

 String filename = Files.getNameWithoutExtension(path); System.out.println(filename); //prints foo 

Si está en Android, puede usar esto:

 String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName()); 

Para tener en cuenta los nombres de archivo sin caracteres antes del punto, debe usar esa ligera variación de la respuesta aceptada:

 String extension = ""; int i = fileName.lastIndexOf('.'); if (i >= 0) { extension = fileName.substring(i+1); } 

 "file.doc" => "doc" "file.doc.gz" => "gz" ".doc" => "doc" 

Mi sucio y puede ser el más pequeño usando String.replaceAll :

 .replaceAll("^.*\\.(.*)$", "$1") 

Tenga en cuenta que primero * es codicioso, por lo que captará la mayor cantidad de caracteres posibles en la medida de lo posible y, a continuación, se dejará el último punto y la extensión del archivo.

Este es un método probado

 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(); } 

Y caso de prueba:

 @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")); } 

Qué tal (usando Java 1.5 RegEx):

  String[] split = fullFileName.split("\\."); String ext = split[split.length - 1]; 

Si planea usar Apache commons-io, y solo quiere verificar la extensión del archivo y luego hacer alguna operación, puede usar esto , aquí hay un fragmento:

 if(FilenameUtils.isExtension(file.getName(),"java")) { someoperation(); } 

¿Qué tal JFileChooser? No es sencillo, ya que tendrá que analizar su salida final …

 JFileChooser filechooser = new JFileChooser(); File file = new File("your.txt"); System.out.println("the extension type:"+filechooser.getTypeDescription(file)); 

que es un tipo MIME …

OK … Olvidé que no quieres saber su tipo MIME.

Código interesante en el siguiente enlace: 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; } 

Pregunta relacionada: ¿Cómo recorte una extensión de archivo desde una cadena en Java?

Este es un método que maneja .tar.gz correctamente, incluso en una ruta con puntos en nombres de directorio:

 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 se crea para hacer que afterLastBackslash más rápido, ya que no tendrá que buscar toda la cadena si hay algunas barras en ella.

El char[] dentro de la String original se reutiliza, no agrega desperdicios allí, y la JVM probablemente notará que afterLastSlash es basura inmediatamente para colocarla en la stack en lugar del montón .

Como es obvio por todas las otras respuestas, no hay una función “incorporada” adecuada. Este es un método seguro y simple.

 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; } 

Aquí está la versión con Opcional como valor de retorno (porque no puede estar seguro de que el archivo tenga una extensión) … también verificaciones de cordura …

 import java.io.File; import java.util.Optional; public class GetFileExtensionTool { public static Optional 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('.')); 

la extensión debería tener “.txt” en ella cuando se ejecuta.

 String extension = com.google.common.io.Files.getFileExtension("fileName.jpg"); 

Aquí hice un pequeño método (aunque no tan seguro y no comprueba muchos errores), pero si solo tú estás progtwigndo un progtwig java general, esto es más que suficiente para encontrar el tipo de archivo. Esto no funciona para tipos de archivos complejos, pero normalmente no se usan tanto.

  public static String getFileType(String path){ String fileType = null; fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase(); return fileType; } 

Obtener la extensión de archivo del nombre del archivo

 /** * 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. * 

* This method returns the textual part of the filename after the last dot. * There must be no directory separator after the dot. *

 * foo.txt --> "txt" * a/b/c.jpg --> "jpg" * a/b.txt/c --> "" * a/b/c --> "" * 

*

* 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. *

* 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. *

* 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. *

* This method will handle a file in either Unix or Windows format. * The position of the last forward or backslash is returned. *

* 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); }

Créditos

  1. Copiado de Apache FileNameUtils Class – 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

¿Qué hay de la versión REGEX :

 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)); } 

o con extensión nula compatible:

 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); 

resultado para * nix:
ruta: / root / docs /
nombre: readme
Extensión: txt

para windows, parsePath (“c: \ windows \ readme.txt”):
ruta de acceso: c: \ windows \
nombre: readme
Extensión: txt

Sin el uso de ninguna biblioteca, puede utilizar el método String dividido de la siguiente manera:

  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()); 

devolver “.txt”

si solo quieres “txt”, haz path.lastIndexOf(".") + 1

Solo una alternativa basada en expresiones regulares. No tan rápido, no tan bueno.

 Pattern pattern = Pattern.compile("\\.([^.]*)$"); Matcher matcher = pattern.matcher(fileName); if (matcher.find()) { String ext = matcher.group(1); } 

Esta pregunta en particular me da muchos problemas, entonces encontré una solución muy simple para este problema que estoy publicando aquí.

 file.getName().toLowerCase().endsWith(".txt"); 

Eso es.

Encontré una mejor manera de encontrar extensión mezclando todas las respuestas anteriores

 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)); } 

prueba esto.

 String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg'] extension[1] // jpg 
  @Test public void getFileExtension(String fileName){ String extension = null; List 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()); } 

Puede usar la característica Java7 del paquete java.io

 Files.probeContentType(path); 

Consulte el siguiente fragmento de código

 public static String returnContentType(String pathText) throws Exception { // obtain Path object that represents the file Path path = Paths.get(pathText); // probe the content String contentType = Files.probeContentType(path); // return content type return contentType; } 

Java tiene una forma integrada de manejar esto, en la clase java.nio.file.Files , que puede funcionar para sus necesidades:

 File f = new File("/path/to/file/foo.txt"); String ext = Files.probeContentType(f.toPath()); if(ext.equalsIgnoreCase("txt")) do whatever; 

Tenga en cuenta que este método estático utiliza las especificaciones que se encuentran aquí para recuperar el “tipo de contenido”, que puede variar.