193 votes

Comment découper une extension de fichier à partir d'une chaîne de caractères en Java ?

Quel est le moyen le plus efficace de couper le suffixe en Java, comme ceci :

title part1.txt
title part2.html
=>
title part1
title part2

2 votes

Efficace au niveau du code, c'est ce que vous voulez dire j'espère, pas au niveau du CPU

3 votes

Il ne demandait pas comment le faire, mais quelle était la méthode la plus efficace. Je suis venu ici pour chercher la même chose.

311voto

skaffman Points 197885

C'est le genre de code que nous ne devrions pas faire nous-mêmes. Utilisez les bibliothèques pour les choses banales, gardez votre cerveau pour les choses plus difficiles.

Dans ce cas, je recommande d'utiliser FilenameUtils.removeExtension() de Apache Commons IO

7 votes

Pour 95% des projets, cela devrait être la réponse acceptée. La réécriture de ce type de code est la cause première de nombreux maux de tête !

1 votes

Il suffit d'ajouter la ligne suivante dans gradle pour ajouter la dépendance : - compile 'commons-io:commons-io:2.6'.

14 votes

Si vous avez déjà Apache Commons I/O dans votre projet, c'est bien. Mais si c'est tout ce dont vous avez besoin, vous ajoutez (au moins) 2,5 Mo de poids mort à votre projet pour quelque chose qui peut être facilement fait avec une seule ligne.

253voto

str.substring(0, str.lastIndexOf('.'))

10 votes

Celle-ci doit être assignée à une nouvelle variable car str n'est pas modifié.

54 votes

À manipuler avec précaution : une exception sera levée si le nom du fichier n'a pas de suffixe.

24 votes

Qu'en est-il de archive.tar.bz2 ?

92voto

coobird Points 70356

Comme l'utilisation du String.substring et String.lastIndex en une seule ligne est bien, il y a quelques problèmes en termes de capacité à faire face à certains chemins de fichiers.

Prenons par exemple le chemin suivant :

a.b/c

L'utilisation de la phrase unique aura pour résultat :

a

C'est faux.

Le résultat aurait dû être c mais comme le fichier n'a pas d'extension, mais que le chemin d'accès comporte un répertoire avec une extension . dans le nom, la méthode à une ligne a été trompée en donnant une partie du chemin comme nom de fichier, ce qui n'est pas correct.

Nécessité de contrôles

Inspiré par La réponse de skaffman j'ai jeté un coup d'oeil à la FilenameUtils.removeExtension de la méthode Apache Commons IO .

Afin de recréer son comportement, j'ai écrit quelques tests que la nouvelle méthode devrait remplir, qui sont les suivants :

Path                  Filename
--------------        --------
a/b/c                 c
a/b/c.jpg             c
a/b/c.jpg.jpg         c.jpg

a.b/c                 c
a.b/c.jpg             c
a.b/c.jpg.jpg         c.jpg

c                     c
c.jpg                 c
c.jpg.jpg             c.jpg

(Et c'est tout ce que j'ai vérifié - il y a probablement d'autres vérifications qui devraient être en place et que j'ai négligées).

La mise en œuvre

Voici ma mise en œuvre pour le removeExtension méthode :

public static String removeExtension(String s) {

    String separator = System.getProperty("file.separator");
    String filename;

    // Remove the path upto the filename.
    int lastSeparatorIndex = s.lastIndexOf(separator);
    if (lastSeparatorIndex == -1) {
        filename = s;
    } else {
        filename = s.substring(lastSeparatorIndex + 1);
    }

    // Remove the extension.
    int extensionIndex = filename.lastIndexOf(".");
    if (extensionIndex == -1)
        return filename;

    return filename.substring(0, extensionIndex);
}

Exécuter ceci removeExtension avec les tests ci-dessus donnent les résultats indiqués ci-dessus.

La méthode a été testée avec le code suivant. Comme il a été exécuté sous Windows, le séparateur de chemin est un signe \ qui doit être échappé avec un \ lorsqu'il est utilisé dans le cadre d'un String littéral.

System.out.println(removeExtension("a\\b\\c"));
System.out.println(removeExtension("a\\b\\c.jpg"));
System.out.println(removeExtension("a\\b\\c.jpg.jpg"));

System.out.println(removeExtension("a.b\\c"));
System.out.println(removeExtension("a.b\\c.jpg"));
System.out.println(removeExtension("a.b\\c.jpg.jpg"));

System.out.println(removeExtension("c"));
System.out.println(removeExtension("c.jpg"));
System.out.println(removeExtension("c.jpg.jpg"));

Les résultats sont les suivants :

c
c
c.jpg
c
c
c.jpg
c
c
c.jpg

Les résultats sont les résultats souhaités décrits dans le test que la méthode doit remplir.

4 votes

Excellente réponse. Y a-t-il une raison particulière pour laquelle vous utilisez System.getProperty("file.separator") et pas seulement File.separator ?

2 votes

Un mot d'avertissement : Cette solution supprime également le chemin précédent, et pas seulement l'extension, contrairement à la méthode Apache Commons IO.

3 votes

Il semble que cela échouera pour le /path/to/.htaccess

19voto

Edward Falk Points 3650

BTW, dans mon cas, lorsque j'ai voulu une solution rapide pour supprimer une extension spécifique, c'est à peu près ce que j'ai fait :

  if (filename.endsWith(ext))
    return filename.substring(0,filename.length() - ext.length());
  else
    return filename;

17voto

Jherico Points 12554
String foo = "title part1.txt";
foo = foo.substring(0, foo.lastIndexOf('.'));

4 votes

Non, il peut y avoir plus d'un '.' ; vous voulez lastIndexOf('.')

0 votes

-1 pour ne pas avoir utilisé la méthode que je pensais que vous utilisiez. C'est maintenant un total de +0 de ma part. Changez-le vite ! ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X