Comment obtenir le nom de fichier sans l'extension en Java?


Réponses:


429

Si vous, comme moi, préférez utiliser du code de bibliothèque où ils ont probablement pensé à tous les cas spéciaux, tels que ce qui se passe si vous passez null ou des points dans le chemin mais pas dans le nom de fichier, vous pouvez utiliser ce qui suit:

import org.apache.commons.io.FilenameUtils;
String fileNameWithOutExt = FilenameUtils.removeExtension(fileNameWithExt);

61
vous pouvez également utiliser FilenameUtils.getBasename pour passer directement d'une chaîne de chemin d'accès à un nom de fichier sans extension.
Ian Durkan

2
Le plus simple est bien sûr d'exécuter maven :-) Sinon, voir: commons.apache.org/io
Ulf Lindback

8
Pour ceux qui préfèrent la goyave, cela peut aussi le faire . (Ces jours-ci, je ne me sens pas très bien à l'idée d'ajouter des dépendances Apache Commons, bien que ces bibliothèques aient été historiquement très utiles.)
Jonik

3
Bien que Guava et Commons-IO puissent offrir un peu plus, vous seriez surpris du nombre de méthodes pratiques déjà incluses dans JDK 7 avec java.nio.file.Fileset Path- telles que la résolution de répertoires de base, la copie / le déplacement d'une ligne de fichiers, l'obtention uniquement du nom de fichier etc.
Don Cheadle

3
@Lan Durkan actuellement FilenameUtils.getBaseName avec un N majuscule
Slow Harry

153

Le moyen le plus simple consiste à utiliser une expression régulière.

fileNameWithOutExt = "test.xml".replaceFirst("[.][^.]+$", "");

L'expression ci-dessus supprimera le dernier point suivi d'un ou plusieurs caractères. Voici un test unitaire de base.

public void testRegex() {
    assertEquals("test", "test.xml".replaceFirst("[.][^.]+$", ""));
    assertEquals("test.2", "test.2.xml".replaceFirst("[.][^.]+$", ""));
}

11
Regex n'est pas aussi facile à utiliser que la solution de bibliothèque ci-dessus. Cela fonctionne, mais regarder le code (sans avoir à interpréter le REGEX) n'est pas évident ce qu'il fait.
Gustavo Litovsky

5
@GustavoLitovsky Android n'est pas fourni avec org.apache.commons. À ma connaissance, c'est la seule façon de le faire dans Android.
Liam George Betsworth

1
/ * la regex suivante supprime également le chemin * / "/the/path/name.extension".replaceAll(".*[\\\\/ diplomatique|\\.[^\\.ram*$", "") ;
daggett

1
J'ajouterais des barres obliques à la deuxième classe de caractères pour m'assurer que vous n'êtes pas trébuché par un chemin comme "/foo/bar.x/baz"
chrisinmtown

53

Voir le programme de test suivant:

public class javatemp {
    static String stripExtension (String str) {
        // Handle null case specially.

        if (str == null) return null;

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

    public static void 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."));
    }
}

qui génère:

test.xml   -> test
test.2.xml -> test.2
test       -> test
test.      -> test

Quelle est l'extension de foo.tar.gz? Je peux voir pourquoi .tar.gzserait ce que vous voudriez.
tchrist

5
@tchrist, foo.tar.gzest une version gzippée de foo.tarsorte que vous pouvez également affirmer que gzc'était l'extension. Tout dépend de la façon dont vous définissez l'extension.
paxdiablo

2
que faire avec des fichiers comme .gitignore?
michael nesterenko

comme vous le savez, le nom de classe en java ne doit jamais commencer par une petite lettre!
AnujKu

7
Si c'était une règle, le langage l'appliquerait. Comme ce n'est pas le cas, il s'agit d'une ligne directrice, quelle que soit sa force. En tout cas, cela n'a absolument rien à voir avec la question et la réponse.
paxdiablo

47

Voici l'ordre de la liste consolidée par ma préférence.

Utilisation d'apache commons

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

Utilisation de Google Guava (si vous l'utilisez déjà)

import com.google.common.io.Files;
String fileNameWithOutExt = Files.getNameWithoutExtension(fileName);

Ou en utilisant Core Java

1)

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

2)

if (fileName.indexOf(".") > 0) {
   return fileName.substring(0, fileName.lastIndexOf("."));
} else {
   return fileName;
}

3)

private static final Pattern ext = Pattern.compile("(?<=.)\\.[^.]+$");

public static String getFileNameWithoutExtension(File file) {
    return ext.matcher(file.getName()).replaceAll("");
}

API Liferay

import com.liferay.portal.kernel.util.FileUtil; 
String fileName = FileUtil.stripExtension(file.getName());

42

Si votre projet utilise Guava (14.0 ou plus récent), vous pouvez continuer Files.getNameWithoutExtension().

(Essentiellement le même que FilenameUtils.removeExtension()pour Apache Commons IO, comme le suggère la réponse la plus votée . Je voulais juste souligner que la goyave le fait aussi. Personnellement, je ne voulais pas ajouter de dépendance à Commons — ce qui me semble un peu une relique— juste à cause de cela.)


2
en fait, c'est plus commeFilenameUtils.getBaseName()
Angelo.Hannes

en fait, la goyave est une bibliothèque tellement instable que j'évite de l'utiliser quand je le peux. préfère une relique stable que des expériences par googel
Slava

8

Ci-dessous est la référence de https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/util/FileUtil.java

/**
 * 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
 */
public static String getBaseName(String fileName) {
    int index = fileName.lastIndexOf('.');
    if (index == -1) {
        return fileName;
    } else {
        return fileName.substring(0, index);
    }
}

1
Belle information, mais les utilisateurs doivent être conscients des cas comme ".htaccess", où cette méthode retournera "".
Markus Schulte

6

Si vous n'aimez pas importer la version complète d'apache.commons, j'ai extrait la même fonctionnalité:

public class StringUtils {
    public static String getBaseName(String filename) {
        return removeExtension(getName(filename));
    }

    public static int indexOfLastSeparator(String filename) {
        if(filename == null) {
            return -1;
        } else {
            int lastUnixPos = filename.lastIndexOf(47);
            int lastWindowsPos = filename.lastIndexOf(92);
            return Math.max(lastUnixPos, lastWindowsPos);
        }
    }

    public static String getName(String filename) {
        if(filename == null) {
            return null;
        } else {
            int index = indexOfLastSeparator(filename);
            return filename.substring(index + 1);
        }
    }

    public static String removeExtension(String filename) {
        if(filename == null) {
            return null;
        } else {
            int index = indexOfExtension(filename);
            return index == -1?filename:filename.substring(0, index);
        }
    }

    public static int indexOfExtension(String filename) {
        if(filename == null) {
            return -1;
        } else {
            int extensionPos = filename.lastIndexOf(46);
            int lastSeparator = indexOfLastSeparator(filename);
            return lastSeparator > extensionPos?-1:extensionPos;
        }
    }
}

4

Alors que je suis un grand partisan de la réutilisation des bibliothèques, le JAR org.apache.commons.io est de 174 Ko, ce qui est notablement important pour une application mobile.

Si vous téléchargez le code source et jetez un oeil à leur classe FilenameUtils, vous pouvez voir qu'il existe de nombreux utilitaires supplémentaires, et il prend en charge les chemins Windows et Unix, ce qui est très agréable.

Cependant, si vous voulez juste quelques méthodes utilitaires statiques à utiliser avec les chemins de style Unix (avec un séparateur "/"), vous pouvez trouver le code ci-dessous utile.

La removeExtensionméthode conserve le reste du chemin avec le nom de fichier. Il y a aussi un similaire getExtension.

/**
 * Remove the file extension from a filename, that may include a path.
 * 
 * e.g. /path/to/myfile.jpg -> /path/to/myfile 
 */
public static String removeExtension(String filename) {
    if (filename == null) {
        return null;
    }

    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
 */
public static String getExtension(String filename) {
    if (filename == null) {
        return null;
    }

    int index = indexOfExtension(filename);

    if (index == -1) {
        return filename;
    } else {
        return filename.substring(index);
    }
}

private static final char EXTENSION_SEPARATOR = '.';
private static final char DIRECTORY_SEPARATOR = '/';

public static int indexOfExtension(String filename) {

    if (filename == null) {
        return -1;
    }

    // Check that no directory separator appears after the 
    // EXTENSION_SEPARATOR
    int 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;
}

1
public static String getFileExtension(String fileName) {
        if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null;
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    public static String getBaseFileName(String fileName) {
        if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null;
        return fileName.substring(0,fileName.lastIndexOf("."));
    }

1

Le moyen le plus simple d'obtenir le nom d'un chemin relatif ou d'un chemin complet consiste à utiliser

import org.apache.commons.io.FilenameUtils; FilenameUtils.getBaseName(definitionFilePath)


0

Vous pouvez le diviser par "." et sur l'index 0 est le nom du fichier et sur 1 est l'extension, mais j'inclinerais pour la meilleure solution avec FileNameUtils de apache.commons-io comme cela a été mentionné dans le premier article. Il n'est pas nécessaire de le supprimer, mais il suffit:

String fileName = FilenameUtils.getBaseName("test.xml");


0

Utilisation FilenameUtils.removeExtensiondepuis Apache Commons IO

Exemple:

Vous pouvez fournir le nom de chemin complet ou uniquement le nom de fichier .

String myString1 = FilenameUtils.removeExtension("helloworld.exe"); // returns "helloworld"
String myString2 = FilenameUtils.removeExtension("/home/abc/yey.xls"); // returns "yey"

J'espère que cela t'aides ..


C'est déjà dans la réponse acceptée, quel est l'intérêt de ce post?
Tom

0

La manière fluide:

public static String fileNameWithOutExt (String fileName) {
    return Optional.of(fileName.lastIndexOf(".")).filter(i-> i >= 0)
            .map(i-> fileName.substring(0, i)).orElse(fileName);
}

0

Pour rester simple, utilisez la méthode String.replaceAll () de Java comme suit:

String fileNameWithExt = "test.xml";
String fileNameWithoutExt
   = fileNameWithExt.replaceAll( "^.*?(([^/\\\\\\.]+))\\.[^\\.]+$", "$1" );

Cela fonctionne également lorsque fileNameWithExt inclut le chemin d'accès complet.


0

Vous pouvez utiliser la fonction de division Java pour séparer le nom de fichier de l'extension, si vous êtes sûr qu'il n'y a qu'un seul point dans le nom de fichier pour l'extension.

File filename = new File('test.txt'); File.getName().split("[.]");

donc le split[0]retournera "test" et split [1] retournera "txt"


-3

Essayez le code ci-dessous. Utilisation des fonctions de base de Java. Il prend en charge les Strings avec extension, et sans extension (sans le '.'caractère). Le cas du multiple '.'est également couvert.

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

Vous pouvez l'adapter pour travailler avec des nullchaînes.


1
C'est une mauvaise pratique d'implémenter vous-même ce type de fonctionnalité. À première vue, la tâche semble être extrêmement évidente , mais dans la pratique, vous serez confronté à de nombreuses situations exceptionnelles (comme s'il n'y a pas .de nom de fichier ou que le fichier est une sauvegarde et a un nom similaire document.docx.backup, etc.). Il est beaucoup plus fiable d'utiliser une bibliothèque externe qui traite toutes ces situations exceptionnelles pour vous.
ivstas

1
D'autre part, l'ajout de nombreuses bibliothèques à votre projet l'agrandira. Des choses si simples comme celle-ci pourraient être faites par vous-même.
Nicolas Tyler

1
Vous ne devriez pas le faire vous-même. C'est difficile: des fichiers sans extension mais. en chemin, chemins ftp, fenêtres et barres obliques unix, liens symboliques etc ... Vous échouerez certainement et en essayant de gagner un peu de mémoire vous ajouterez beaucoup d'instabilité. Copiez au minimum les sources du code établi si les licences le permettent.
Jonathan Nappee

Ce code ressemble à celui d'Amit Mishra, à l'exception de celui intimidant 'if (! Str.contains ("."))'
Broken_Window

échouerait dans le cas suivant "/someFolder/some.other.folder/someFileWithoutExtention". Première chose qui m'est venue à l'esprit après 2 secondes .. Je suis sûr que je pourrais trouver une tonne d'autres exemples.
Newtopian
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.