web-dev-qa-db-fra.com

Comment obtenir l'extension de fichier d'un fichier en Java?

Juste pour être clair, je ne cherche pas le type MIME.

Disons que j'ai l'entrée suivante: /path/to/file/foo.txt

Je voudrais un moyen de casser cette entrée, en particulier dans .txt pour l'extension. Existe-t-il une méthode intégrée permettant de faire cela en Java? Je voudrais éviter d'écrire mon propre analyseur.

399
longda

Dans ce cas, utilisez FilenameUtils.getExtension from Apache Commons IO

Voici un exemple d'utilisation (vous pouvez spécifier le chemin complet ou simplement le nom du fichier):

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

Avez-vous vraiment besoin d'un "analyseur" pour cela?

String extension = "";

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

En supposant que vous traitez avec des noms de fichiers simples ressemblant à Windows, pas quelque chose comme archive.tar.gz.

Btw, pour le cas où un répertoire peut avoir un '.', Mais le nom du fichier lui-même n'a pas (comme /path/to.a/file), vous pouvez faire

String extension = "";

int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));

if (i > p) {
    extension = fileName.substring(i+1);
}
270
EboMike
private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}
87
spectre

Si vous utilisez la bibliothèque Guava, vous pouvez utiliser la classe Files utility. Il a une méthode spécifique, getFileExtension() . Par exemple:

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

De plus, vous pouvez également obtenir le nom du fichier avec une fonction similaire, getNameWithoutExtension () :

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

Si vous utilisez Android, vous pouvez utiliser ceci:

String ext = Android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
28
intrepidis

Pour prendre en compte les noms de fichiers sans caractères before le point, vous devez utiliser cette légère variation de la réponse acceptée:

String extension = "";

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

"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"
15
Sylvain Leroux

My dirty and tiniest using String.replaceAll :

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

Notez que le premier * est gourmand; il saisira donc le plus de caractères possibles, puis les derniers points et fichiers restants.

10
Ebrahim Byagowi

C'est une méthode testée

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

Et cas de test:

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

Comme cela ressort de toutes les autres réponses, il n’existe pas de fonction "intégrée" adéquate. C'est une méthode simple et sûre.

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

Pourquoi pas (avec Java 1.5 RegEx):

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

Si vous prévoyez d'utiliser Apache commons-io et que vous souhaitez simplement vérifier l'extension du fichier, puis effectuer quelques opérations, vous pouvez utiliser this , voici un extrait:

if(FilenameUtils.isExtension(file.getName(),"Java")) {
    someoperation();
}
6
Geng Jiawen

Voici une méthode qui gère correctement .tar.gz, même dans un chemin avec des points dans les noms de répertoire:

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 est créé pour faciliter la recherche de afterLastBackslash, car il n'aura pas à rechercher toute la chaîne s'il y a des barres obliques.

Le char[] à l'intérieur de la String d'origine est réutilisé, en n'y ajoutant aucun déchet, et la machine virtuelle Java remarquera probablement que afterLastSlash est immédiatement un déchet afin de le mettre sur la pile au lieu du tas .

4
Olathe

Que diriez-vous de JFileChooser? Ce n'est pas simple, vous devrez analyser sa sortie finale ...

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

qui est un type MIME ...

OK ... j'oublie que vous ne voulez pas connaître son type MIME.

Code intéressant dans le lien suivant: 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;
}

Question connexe: Comment puis-je couper une extension de fichier à partir d'une chaîne en Java?

4
eee

Voici la version avec facultatif comme valeur de retour (car vous ne pouvez pas être sûr que le fichier a une extension) ... également des contrôles de cohérence ... 

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

Que diriez-vous deREGEXversion:

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

ou avec l'extension null supportée:

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

résultat pour * nix:
chemin:/root/docs /
name: readme
Extention: txt

pour windows, parsePath ("c:\windows\readme.txt"):
chemin: c:\windows \
name: readme
Extention: txt

2
Dmitry Sokolyuk

Obtenir une extension de fichier à partir d'un nom de fichier

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

Crédits

  1. Copié depuis la classe 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
1
Vasanth

Sans utiliser aucune bibliothèque, vous pouvez utiliser la méthode String divisée comme suit:

        String[] splits = fileNames.get(i).split("\\.");

        String extension = "";

        if(splits.length >= 2)
        {
            extension = splits[splits.length-1];
        }
1
Farah
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");
1
Alfaville

Voici un autre one-liner pour Java 8. 

String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)

Cela fonctionne comme suit:

  1. Fractionner la chaîne en un tableau de chaînes en utilisant "."
  2. Convertir le tableau en un flux
  3. Utilisez réduire pour obtenir le dernier élément du flux, c’est-à-dire l’extension de fichier.
// Modified from EboMike's answer

String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));

l'extension devrait avoir ".txt" dedans quand elle est lancée.

1
longda

Ici, j’ai fait une petite méthode (mais pas très sûre et ne vérifie pas beaucoup d’erreurs), mais si c’est seulement vous qui programmez un programme Java général, c’est largement suffisant pour trouver le type de fichier. Cela ne fonctionne pas pour les types de fichiers complexes, mais ceux-ci ne sont généralement pas utilisés autant. 

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

extension = path.substring(path.lastIndexOf("."), path.length());

retourne ".text"

si vous voulez seulement du "texte", faites path.lastIndexOf(".") + 1

1
Clément Chameyrat

Cette question particulière me donne beaucoup de peine alors j'ai trouvé une solution très simple pour ce problème que je poste ici.

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

C'est tout.

0
vikram Bhardwaj

Juste une alternative basée sur une expression régulière. Pas si vite, pas si bon. 

Pattern pattern = Pattern.compile("\\.([^.]*)$");
Matcher matcher = pattern.matcher(fileName);

if (matcher.find()) {
    String ext = matcher.group(1);
}
0
serhiy.h

J'aime la simplicité de la réponse de spectre . Dans l'un de ses commentaires, un lien vers une autre réponse corrige les points dans les chemins de fichiers, sur une autre question, faite par EboMike .

Sans implémenter une sorte d'API tierce, je suggère:

private String getFileExtension(File file) {

    String name = file.getName().substring(Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')) < 0 ? 0 : Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')));
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf + 1); // doesn't return "." with extension
}

Quelque chose comme cela peut être utile dans, disons, toutes les méthodes write d'ImageIO, où le format de fichier doit être passé.

Pourquoi utiliser une API tierce quand on peut faire du bricolage?

0
DDPWNAGE

J'ai trouvé un meilleur moyen de trouver l'extension en mélangeant toutes les réponses ci-dessus

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));
    }
0
Raghav Satyadev