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:
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.
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:
publicclass javatemp {staticString stripExtension (String str){// Handle null case specially.if(str ==null)returnnull;// 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);}publicstaticvoid 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
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)
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);}
(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.)
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
/**
* 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
*/publicstaticString getBaseName(String fileName){int index = fileName.lastIndexOf('.');if(index ==-1){return fileName;}else{return fileName.substring(0, index);}}
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
*/publicstaticString removeExtension(String filename){if(filename ==null){returnnull;}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
*/publicstaticString getExtension(String filename){if(filename ==null){returnnull;}int index = indexOfExtension(filename);if(index ==-1){return filename;}else{return filename.substring(index);}}privatestaticfinalchar EXTENSION_SEPARATOR ='.';privatestaticfinalchar DIRECTORY_SEPARATOR ='/';publicstaticint indexOfExtension(String filename){if(filename ==null){return-1;}// Check that no directory separator appears after the // EXTENSION_SEPARATORint 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;}
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:
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.
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 .
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.
Antworten:
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:
quelle
java.nio.file.Files
und enthalten sindPath
- wie das Auflösen von Basisverzeichnissen, das einzeilige Kopieren / Verschieben von Dateien und das Abrufen nur des Dateinamens usw.Am einfachsten ist es, einen regulären Ausdruck zu verwenden.
Der obige Ausdruck entfernt den letzten Punkt, gefolgt von einem oder mehreren Zeichen. Hier ist ein grundlegender Komponententest.
quelle
org.apache.commons
. Soweit mir bekannt ist, ist dies die einzige Möglichkeit, dies in Android zu tun.Siehe folgendes Testprogramm:
welche Ausgänge:
quelle
foo.tar.gz
? Ich kann sehen, warum.tar.gz
das sein würde, was du willst.foo.tar.gz
ist eine gezippte Version von,foo.tar
also könnte man auch argumentieren, dass diesgz
die Erweiterung war. Alles hängt davon ab, wie Sie die Erweiterung definieren..gitignore
?Hier ist die konsolidierte Listenreihenfolge nach meinen Wünschen.
Verwenden von Apache Commons
Verwenden von Google Guava (Wenn Sie es bereits verwenden)
Oder mit Core Java
1)
2)
3)
Liferay API
quelle
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.)quelle
FilenameUtils.getBaseName()
Unten finden Sie eine Referenz von https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/util/FileUtil.java
quelle
Wenn Sie nicht die vollständige Datei apache.commons importieren möchten, habe ich dieselbe Funktionalität extrahiert:
quelle
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
removeExtension
Methode behält den Rest des Pfads zusammen mit dem Dateinamen bei. Es gibt auch eine ähnlichegetExtension
.quelle
quelle
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)
quelle
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");
quelle
Verwendung
FilenameUtils.removeExtension
von Apache Commons IOBeispiel:
Sie können den vollständigen Pfadnamen oder nur den Dateinamen angeben .
Hoffe das hilft ..
quelle
Der fließende Weg:
quelle
Verwenden Sie die String.replaceAll () -Methode von Java wie folgt:
Dies funktioniert auch, wenn fileNameWithExt den vollständig qualifizierten Pfad enthält.
quelle
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.quelle
Versuchen Sie den folgenden Code. Verwenden der grundlegenden Java-Grundfunktionen. Es kümmert sich um
String
s mit Erweiterung und ohne Erweiterung (ohne den'.'
Charakter). Der Fall der Mehrfachbehandlung'.'
wird ebenfalls behandelt.Sie können es anpassen, um mit
null
Zeichenfolgen zu arbeiten .quelle
.
Dateinamen oder eine Datei ist ein Backup und hat einen Namen wiedocument.docx.backup
usw.). Es ist viel zuverlässiger, eine externe Bibliothek zu verwenden, die all diese Ausnahmesituationen für Sie behandelt.