Wie bekomme ich den Dateinamen ohne die Erweiterung in Java?

Antworten:

429

Wenn Sie, wie ich, lieber einen Bibliothekscode verwenden möchten, bei dem sie wahrscheinlich an alle Sonderfälle gedacht haben, z. B. was passiert, wenn Sie Null oder Punkte im Pfad, aber nicht im Dateinamen übergeben, können Sie Folgendes verwenden:

import org.apache.commons.io.FilenameUtils;
String fileNameWithOutExt = FilenameUtils.removeExtension(fileNameWithExt);
Ulf Lindback
quelle
61
Sie können auch FilenameUtils.getBasename verwenden, um direkt von einer Pfadzeichenfolge zu einem Dateinamen ohne Erweiterung zu wechseln.
Ian Durkan
2
Am einfachsten ist es natürlich, Maven laufen zu lassen :-) Ansonsten siehe: commons.apache.org/io
Ulf Lindback
8
Für diejenigen, die Guave bevorzugen, kann es dies auch tun . (
Heutzutage
3
Während Guava und Commons-IO möglicherweise ein kleines Extra bieten, werden Sie überrascht sein, wie viele praktische Methoden bereits in JDK 7 mit java.nio.file.Filesund enthalten sind Path- wie das Auflösen von Basisverzeichnissen, das einzeilige Kopieren / Verschieben von Dateien und das Abrufen nur des Dateinamens usw.
Don Cheadle
3
@ Lan Durkan derzeit FilenameUtils.getBaseName mit Großbuchstaben N
Slow Harry
153

Am einfachsten ist es, einen regulären Ausdruck zu verwenden.

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

Der obige Ausdruck entfernt den letzten Punkt, gefolgt von einem oder mehreren Zeichen. Hier ist ein grundlegender Komponententest.

public void testRegex() {
    assertEquals("test", "test.xml".replaceFirst("[.][^.]+$", ""));
    assertEquals("test.2", "test.2.xml".replaceFirst("[.][^.]+$", ""));
}
Brianegge
quelle
11
Regex ist nicht so einfach zu bedienen wie die oben genannte Bibliothekslösung. Es funktioniert, aber das Betrachten des Codes (ohne den REGEX interpretieren zu müssen) ist nicht offensichtlich, was es tut.
Gustavo Litovsky
5
@GustavoLitovsky Android wird nicht mitgeliefert org.apache.commons. Soweit mir bekannt ist, ist dies die einzige Möglichkeit, dies in Android zu tun.
Liam George Betsworth
1
/ * Der folgende reguläre Ausdruck entfernt auch den Pfad * / "/the/path/name.extension".replaceAll(".*[\\\\/‹|\\.[^\\.‹*$", "") ;;
Daggett
1
Ich würde der zweiten Zeichenklasse Schrägstriche hinzufügen, um sicherzustellen, dass Sie nicht von einem Pfad wie "/foo/bar.x/baz"
chrisinmtown
53

Siehe folgendes Testprogramm:

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

welche Ausgänge:

test.xml   -> test
test.2.xml -> test.2
test       -> test
test.      -> test
paxdiablo
quelle
Was ist die Erweiterung von foo.tar.gz? Ich kann sehen, warum .tar.gzdas sein würde, was du willst.
Tchrist
5
@tchrist, foo.tar.gzist eine gezippte Version von, foo.taralso könnte man auch argumentieren, dass dies gzdie Erweiterung war. Alles hängt davon ab, wie Sie die Erweiterung definieren.
Paxdiablo
2
Was tun mit Dateien wie .gitignore?
Michael Nesterenko
Wie Sie wissen, sollte der Klassenname in Java niemals mit einem kleinen Buchstaben beginnen!
AnujKu
7
Wenn das eine Regel wäre, würde die Sprache sie durchsetzen. Da dies nicht der Fall ist, handelt es sich um eine Richtlinie, die jedoch dringend empfohlen wird. In jedem Fall ist das für die Frage und Antwort völlig irrelevant.
Paxdiablo
47

Hier ist die konsolidierte Listenreihenfolge nach meinen Wünschen.

Verwenden von Apache Commons

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

Verwenden von Google Guava (Wenn Sie es bereits verwenden)

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

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

Liferay API

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

Wenn Ihr Projekt Guava (14.0 oder neuer) verwendet, können Sie mit gehen Files.getNameWithoutExtension().

(Im Wesentlichen dasselbe wie FilenameUtils.removeExtension()bei Apache Commons IO, wie aus der Antwort mit der höchsten Bewertung hervorgeht. Ich wollte nur darauf hinweisen, dass Guava dies auch tut. Persönlich wollte ich Commons keine Abhängigkeit hinzufügen - was ich für ein Relikt halte - nur deswegen.)

Jonik
quelle
2
Eigentlich ist es eher wieFilenameUtils.getBaseName()
Angelo.Hannes
Eigentlich ist Guave eine so instabile Bibliothek, dass ich es einfach vermeide, sie zu benutzen, wo immer ich kann. lieber ein stabiles Relikt als Experimente von googel
Slava
7

Unten finden Sie eine Referenz von 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);
    }
}
David Cheung
quelle
Nette Informationen, aber Benutzer, beachten Sie Fälle wie ".htaccess", in denen diese Methode "" zurückgibt.
Markus Schulte
6

Wenn Sie nicht die vollständige Datei apache.commons importieren möchten, habe ich dieselbe Funktionalität extrahiert:

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;
        }
    }
}
Hamzeh Soboh
quelle
4

Während ich fest an die Wiederverwendung von Bibliotheken glaube , ist die JAR org.apache.commons.io glaube, beträgt org.apache.commons.io KB, was für eine mobile App bemerkenswert groß ist.

Wenn Sie den Quellcode herunterladen und einen Blick auf die FilenameUtils-Klasse werfen, sehen Sie, dass es viele zusätzliche Dienstprogramme gibt, die Windows- und Unix-Pfade verarbeiten, was alles sehr schön ist.

Wenn Sie jedoch nur einige statische Dienstprogrammmethoden zur Verwendung mit Pfaden im Unix-Stil (mit einem "/" -Trennzeichen) benötigen, ist der folgende Code möglicherweise hilfreich.

Die removeExtensionMethode behält den Rest des Pfads zusammen mit dem Dateinamen bei. Es gibt auch eine ähnliche 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;
}
Dan J.
quelle
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("."));
    }
Gil SH
quelle
1

Der einfachste Weg, um einen Namen vom relativen oder vollständigen Pfad zu erhalten, ist die Verwendung

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

Chetan Nehete
quelle
0

Sie können es durch "." Teilen. und auf Index 0 ist Dateiname und auf 1 ist Erweiterung, aber ich würde für die beste Lösung mit FileNameUtils von apache.commons-io neigen, wie es im ersten Artikel erwähnt wurde. Es muss nicht entfernt werden, aber ausreichend ist:

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

Peter S.
quelle
0

Verwendung FilenameUtils.removeExtensionvon Apache Commons IO

Beispiel:

Sie können den vollständigen Pfadnamen oder nur den Dateinamen angeben .

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

Hoffe das hilft ..

Dulith De Costa
quelle
Das steht schon in der akzeptierten Antwort, worum geht es in diesem Beitrag?
Tom
0

Der fließende Weg:

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

Verwenden Sie die String.replaceAll () -Methode von Java wie folgt:

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

Dies funktioniert auch, wenn fileNameWithExt den vollständig qualifizierten Pfad enthält.

gwc
quelle
0

Sie können die Java-Split-Funktion verwenden, um den Dateinamen von der Erweiterung zu trennen, wenn Sie sicher sind, dass der Dateiname nur einen Punkt für die Erweiterung enthält.

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

Das split[0]wird also "test" zurückgeben und split [1] wird "txt" zurückgeben.

Dänischer Ahmed
quelle
-3

Versuchen Sie den folgenden Code. Verwenden der grundlegenden Java-Grundfunktionen. Es kümmert sich um Strings mit Erweiterung und ohne Erweiterung (ohne den '.'Charakter). Der Fall der Mehrfachbehandlung '.'wird ebenfalls behandelt.

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

Sie können es anpassen, um mit nullZeichenfolgen zu arbeiten .

Sksoni
quelle
1
Es ist ziemlich schlecht, diese Art von Funktionalität selbst zu implementieren. Auf den ersten Blick scheint die Aufgabe äußerst offensichtlich zu sein , aber in der Praxis werden Sie mit vielen Ausnahmesituationen konfrontiert sein (z. B. gibt es keinen .Dateinamen oder eine Datei ist ein Backup und hat einen Namen wie document.docx.backupusw.). Es ist viel zuverlässiger, eine externe Bibliothek zu verwenden, die all diese Ausnahmesituationen für Sie behandelt.
ivstas
1
Wenn Sie jedoch viele Bibliotheken zu Ihrem Projekt hinzufügen, wird es größer. So einfache Dinge wie diese könnten Sie selbst erledigen.
Nicolas Tyler
1
Auf keinen Fall sollten Sie dies selbst tun. Das ist schwer: Dateien ohne Erweiterung aber. In Pfaden, FTP-Pfaden, Windows- und Unix-Schrägstrichen, symbolischen Links usw. werden Sie sicherlich scheitern und wenn Sie versuchen, ein wenig Speicherplatz zu gewinnen, werden Sie eine Menge Instabilität hinzufügen. Kopieren Sie mindestens die Quellen des festgelegten Codes, sofern die Lizenzen dies zulassen.
Jonathan Nappee
Dieser Code sieht aus wie der von Amit Mishra, mit Ausnahme des einschüchternden 'if (! Str.contains ("."))'
Broken_Window
würde im folgenden Fall fehlschlagen "/someFolder/some.other.folder/someFileWithoutExtention". Das erste, was mir nach 2 Sekunden in den Sinn kam. Ich bin sicher, ich könnte mir eine Menge anderer Beispiele einfallen lassen.
Newtopian