Come ottenere il nome file senza l'estensione in Java?


Risposte:


429

Se tu, come me, preferisci utilizzare un codice di libreria in cui probabilmente hanno pensato a tutti i casi speciali, come ad esempio cosa succede se passi null o punti nel percorso ma non nel nome del file, puoi usare quanto segue:

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

61
puoi anche usare FilenameUtils.getBasename per passare direttamente da una stringa di percorso a un nome file senza estensione.
Ian Durkan,

2
Il più semplice è ovviamente eseguire maven :-) Altrimenti vedi: commons.apache.org/io
Ulf Lindback

8
Per coloro che preferiscono la Guava, può farlo anche questo . (Oggi non mi sento molto bene riguardo all'aggiunta delle dipendenze di Apache Commons, anche se storicamente quelle librerie sono state molto utili.)
Jonik,

3
Mentre Guava e Commons-IO possono offrire un piccolo extra, rimarrai sorpreso da quanti metodi di convenienza sono già inclusi in JDK 7 con java.nio.file.Filese Path- come la risoluzione di directory di base, la copia / spostamento di una riga di file, ottenendo solo il nome del file ecc.
Don Cheadle,

3
@Lan Durkan attualmente Nome fileUtils.getBaseName con la maiuscola N
Slow Harry

153

Il modo più semplice è usare un'espressione regolare.

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

L'espressione sopra rimuoverà l'ultimo punto seguito da uno o più caratteri. Ecco un test unitario di base.

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

11
Regex non è facile da usare come la soluzione di libreria sopra. Funziona, ma guardare il codice (senza dover interpretare il REGEX) non è ovvio che cosa fa.
Gustavo Litovsky,

5
@GustavoLitovsky Android non viene fornito in bundle org.apache.commons. Per quanto ne so, questo è l'unico modo per farlo su Android.
Liam George Betsworth,

1
/ * la seguente regex rimuove anche il percorso * / "/the/path/name.extension".replaceAll(".*[\\\\/×|\\.[^\\. ;
Daggett,

1
Aggiungerei barre alla seconda classe di caratteri per assicurarmi di non essere inciampato in un percorso come "/foo/bar.x/baz"
chrisinmtown,

53

Vedi il seguente programma di test:

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

che produce:

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

Qual è l'estensione di foo.tar.gz? Vedo perché .tar.gzsarebbe quello che vorresti.
tchrist,

5
@tchrist, foo.tar.gzè una versione gzip di foo.tarcosì si potrebbe anche sostenere che gzera l'estensione. Tutto dipende da come si definisce l'estensione.
paxdiablo,

2
cosa fare con i file come .gitignore?
michael nesterenko,

come sai il nome della classe in Java non dovrebbe mai iniziare con una lettera minuscola!
AnujKu,

7
Se quella fosse una regola, la lingua la imporrebbe. Dal momento che non lo fa, è una linea guida per quanto fortemente suggerito. In ogni caso, questo è del tutto irrilevante per la domanda e la risposta.
paxdiablo,

47

Ecco l'ordine delle liste consolidato secondo le mie preferenze.

Usando i comuni di Apache

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

Utilizzo di Google Guava (se già in uso)

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

O usando 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

Se il tuo progetto utilizza Guava (14.0 o versioni successive), puoi andare con Files.getNameWithoutExtension().

(Essenzialmente uguale a quello FilenameUtils.removeExtension()di Apache Commons IO, come suggerisce la risposta più votata . Volevo solo sottolineare che Guava fa questo. Personalmente non volevo aggiungere dipendenza a Commons — che ritengo sia un po 'una reliquia— solo per questo.)


2
in realtà è più simile aFilenameUtils.getBaseName()
Angelo.Hannes,

in realtà la guava è una lib così instabile che evito di usarla dove posso. preferisco una reliquia stabile rispetto agli esperimenti di googel
Slava,

8

Di seguito è riportato il riferimento da 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
Informazioni utili, ma gli utenti devono essere consapevoli di casi come ".htaccess", in cui questo metodo restituirà "".
Markus Schulte,

6

Se non ti piace importare l'intero apache.commons, ho estratto la stessa funzionalità:

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

Mentre sono un grande sostenitore del riutilizzo delle librerie, il JAR org.apache.commons.io è di 174 KB, che è notevolmente grande per un'app mobile.

Se scarichi il codice sorgente e dai un'occhiata alla loro classe FilenameUtils, puoi vedere che ci sono molte utilità extra e fa fronte ai percorsi Windows e Unix, il che è delizioso.

Tuttavia, se si desidera solo un paio di metodi di utilità statici da utilizzare con percorsi in stile Unix (con un separatore "/"), è possibile che il codice riportato di seguito sia utile.

Il removeExtensionmetodo conserva il resto del percorso insieme al nome file. C'è anche un simile 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

Si sta utilizzando il modo più semplice per ottenere il nome dal percorso relativo o dal percorso completo

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


0

Puoi dividerlo per "." e sull'indice 0 è il nome del file e su 1 l'estensione, ma propenderei per la migliore soluzione con FileNameUtils di apache.commons-io come è stato menzionato nel primo articolo. Non deve essere rimosso, ma è sufficiente:

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


0

Utilizzare FilenameUtils.removeExtensionda Apache Commons IO

Esempio:

È possibile fornire il nome completo del percorso o solo il nome del file .

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

Spero che questo ti aiuti ..


È già nella risposta accettata, qual è il punto di questo post?
Tom,

0

Il modo fluente:

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

0

Mantenendolo semplice, utilizzare il metodo String.replaceAll () di Java come segue:

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

Questo funziona anche quando fileNameWithExt include il percorso completo.


0

È possibile utilizzare la funzione di divisione java per dividere il nome file dall'estensione, se si è sicuri che nel file sia presente un solo punto che per estensione.

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

così split[0]restituirà "test" e dividere [1] restituirà "txt"


-3

Prova il codice qui sotto. Utilizzo delle funzioni di base di Java. Si prende cura di Strings con estensione e senza estensione (senza il '.'carattere). '.'Viene anche trattato il caso del multiplo .

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

Puoi adattarlo per lavorare con le nullstringhe.


1
È una cattiva pratica implementare questo tipo di funzionalità da soli. A prima vista l'attività sembra essere estremamente ovvia , ma in pratica si troveranno ad affrontare molte situazioni eccezionali (come non esiste un .nome file o un file è un backup e ha un nome simile document.docx.backup, ecc.). È molto più affidabile utilizzare una libreria esterna che si occupa di tutte queste situazioni eccezionali per te.
Ivstas,

1
D'altro canto, l'aggiunta di molte librerie al progetto lo ingrandirà. Così cose semplici come questa potrebbero essere fatte da soli.
Nicolas Tyler,

1
In nessun modo dovresti farlo da solo. Questo è difficile: file senza estensione ma. nel percorso, nei percorsi ftp, nelle finestre e nelle barre unix, nei collegamenti simbolici ecc ... Sicuramente fallirai e provando a guadagnare un po 'di memoria avrai molta instabilità. Almeno copia le fonti del codice stabilito se le licenze lo consentono.
Jonathan Nappee,

Questo codice assomiglia a quello di Amit Mishra, ad eccezione di quello intimidatorio 'if (! Str.contains ("."))'
Broken_Window

fallirebbe nel seguente caso "/someFolder/some.other.folder/someFileWithoutExtention". La prima cosa che mi è venuta in mente dopo 2 secondi .. Sono sicuro che potrei trovare un sacco di altri esempi.
Newtopian,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.