Bagaimana cara mendapatkan nama file dari String yang berisi jalur file Absolute?

236

Stringvariabel berisi nama file C:\Hello\AnotherFolder\The File Name.PDF,. Bagaimana saya hanya mendapatkan nama file The File Name.PDFsebagai String?

Saya berencana untuk membagi string, tetapi itu bukan solusi optimal.

sharon Hwk
sumber
dengan referensi ke issuetracker.google.com/issues/37131215 , itu telah diperbaiki.
Prags

Jawaban:

280

cukup gunakan File.getName ()

File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");
System.out.println(f.getName());

menggunakan metode String :

  File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\")+1));
PermGenError
sumber
Bermanfaat. Terima kasih.
Pooja
Hati-hati dengan nama path dengan "/" bukannya "\"
golimar
278

Alternatif menggunakan Path(Java 7+):

Path p = Paths.get("C:\\Hello\\AnotherFolder\\The File Name.PDF");
String file = p.getFileName().toString();

Perhatikan bahwa pemisahan string \\bergantung pada platform karena pemisah file mungkin bervariasi. Path#getNameurus masalah itu untuk Anda.

assylias
sumber
1
Adakah yang melakukan perbandingan kinerja pada berbagai metode dalam pertanyaan ini?
naksir
@ Crush Saya tidak berpikir bahwa Paths.getmengakses sistem file jadi tidak akan mengharapkan kinerja secara material berbeda dari substring / indexOf.
assylias
7
Kenapa tidak ada di Android? aneh.
Android developer
12
Ya, Path mengatasi masalah ketergantungan platform pada slash / backslash, tetapi hanya jika path file berasal dari mesin yang sama (atau platform). Pertimbangkan ini: Anda mengunggah file dari Internet Explorerdan memiliki path "C:\\Hello\\AnotherFolder\\The File Name.PDF"tetapi kode Anda bekerja pada mesin Unix / Linux maka p.getFileName()akan mengembalikan seluruh path, bukan hanya The File Name.PDF.
nyxz
3
Memanggil toString()sangat canggung.
PetroCliff
53

Menggunakan FilenameUtilsdi Apache Commons IO :

String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");
Binoy Babu
sumber
5
Saya pikir ini mungkin yang terbaik, karena kadang-kadang Anda mungkin harus memproses jalur file dari platform lain
ruiruige1991
Ini adalah yang terbaik karena: Mudah dibaca, paling kuat, objek cludder kurang dalam kode +1
fl0w
32

Mengingat yang StringAnda tanyakan adalah

C:\Hello\AnotherFolder\The File Name.PDF

kita perlu mengekstrak semuanya setelah pemisah terakhir, yaitu. \. Itulah yang kami minati.

Anda dapat melakukan

String fullPath = "C:\\Hello\\AnotherFolder\\The File Name.PDF";
int index = fullPath.lastIndexOf("\\");
String fileName = fullPath.substring(index + 1);

Ini akan mengambil indeks yang terakhir \di Anda Stringdan mengekstrak semua yang datang setelah itu fileName.

Jika Anda memiliki Stringdengan pemisah yang berbeda, sesuaikan lastIndexOfuntuk menggunakan pemisah itu. (Bahkan ada kelebihan yang menerima keseluruhan Stringsebagai pemisah.)

Saya telah menghilangkannya dalam contoh di atas, tetapi jika Anda tidak yakin dari mana Stringasalnya atau apa yang terkandung di dalamnya, Anda akan ingin memvalidasi bahwa lastIndexOfmengembalikan nilai yang tidak negatif karena Javadoc menyatakan itu akan kembali

-1 jika tidak ada kejadian seperti itu

Sotirios Delimanolis
sumber
25

Sejak 1.7

    Path p = Paths.get("c:\\temp\\1.txt");
    String fileName = p.getFileName().toString();
    String directory = p.getParent().toString();
max3d
sumber
11

Anda dapat menggunakan path = C: \ Hello \ AnotherFolder \ TheFileName.PDF

String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());
Rakesh
sumber
Anda harus menggunakan \\ alih-alih \
Anoop Chandrika HarisudhanNair
2
Anda tidak boleh menggunakan salah satu dari mereka karena tergantung platform /di unix dan \`(AND THERE IS A BUG IN THE MARKDOWN PARSER HERE) on windows. You can't know. Use another solution like File` atau Paths.
Otomatis
3
Apakah File.separatorplatform juga tergantung? Atau apakah ini akan berhasil ... String strPath = path.substring(path.lastIndexOf(File.separator)+1, path.length());
Jonathan
File.separator & File.separatorChar keduanya "/" pada versi JIX UND / Linux / macOS, dan keduanya "\" pada versi Windows.
可 可 Jacky
2
File.separatortidak akan selalu berfungsi di sini karena di Windows nama file dapat dipisahkan dengan "/"atau "\\".
DodgyCodeException
10

Jawaban lain tidak cukup berfungsi untuk skenario spesifik saya, di mana saya membaca jalur yang berasal dari OS yang berbeda dengan yang saya gunakan saat ini. Untuk menguraikan, saya menyimpan lampiran email yang disimpan dari platform Windows di server Linux. Nama file yang dikembalikan dari JavaMail API adalah sesuatu seperti 'C: \ temp \ hello.xls'

Solusi saya berakhir dengan:

String filenameWithPath = "C:\\temp\\hello.xls";
String[] tokens = filenameWithPath.split("[\\\\|/]");
String filename = tokens[tokens.length - 1];
javaPhobic
sumber
3

Mempertimbangkan kasus bahwa Java adalah Multiplatform:

int lastPath = fileName.lastIndexOf(File.separator);
if (lastPath!=-1){
    fileName = fileName.substring(lastPath+1);
}
Alejandro Hdz
sumber
1

Suatu metode tanpa ketergantungan dan mengurus .. , . dan duplikat pemisah.

public static String getFileName(String filePath) {
    if( filePath==null || filePath.length()==0 )
        return "";
    filePath = filePath.replaceAll("[/\\\\]+", "/");
    int len = filePath.length(),
        upCount = 0;
    while( len>0 ) {
        //remove trailing separator
        if( filePath.charAt(len-1)=='/' ) {
            len--;
            if( len==0 )
                return "";
        }
        int lastInd = filePath.lastIndexOf('/', len-1);
        String fileName = filePath.substring(lastInd+1, len);
        if( fileName.equals(".") ) {
            len--;
        }
        else if( fileName.equals("..") ) {
            len -= 2;
            upCount++;
        }
        else {
            if( upCount==0 )
                return fileName;
            upCount--;
            len -= fileName.length();
        }
    }
    return "";
}

Kasus cobaan:

@Test
public void testGetFileName() {
    assertEquals("", getFileName("/"));
    assertEquals("", getFileName("////"));
    assertEquals("", getFileName("//C//.//../"));
    assertEquals("", getFileName("C//.//../"));
    assertEquals("C", getFileName("C"));
    assertEquals("C", getFileName("/C"));
    assertEquals("C", getFileName("/C/"));
    assertEquals("C", getFileName("//C//"));
    assertEquals("C", getFileName("/A/B/C/"));
    assertEquals("C", getFileName("/A/B/C"));
    assertEquals("C", getFileName("/C/./B/../"));
    assertEquals("C", getFileName("//C//./B//..///"));
    assertEquals("user", getFileName("/user/java/.."));
    assertEquals("C:", getFileName("C:"));
    assertEquals("C:", getFileName("/C:"));
    assertEquals("java", getFileName("C:\\Program Files (x86)\\java\\bin\\.."));
    assertEquals("C.ext", getFileName("/A/B/C.ext"));
    assertEquals("C.ext", getFileName("C.ext"));
}

Mungkin getFileName agak membingungkan, karena ia mengembalikan nama direktori juga. Ini mengembalikan nama file atau direktori terakhir di jalur.

yavuzkavus
sumber
0

ekstrak nama file menggunakan java regex *.

public String extractFileName(String fullPathFile){
        try {
            Pattern regex = Pattern.compile("([^\\\\/:*?\"<>|\r\n]+$)");
            Matcher regexMatcher = regex.matcher(fullPathFile);
            if (regexMatcher.find()){
                return regexMatcher.group(1);
            }
        } catch (PatternSyntaxException ex) {
            LOG.info("extractFileName::pattern problem <"+fullPathFile+">",ex);
        }
        return fullPathFile;
    }
HJK
sumber
0

Anda dapat menggunakan objek FileInfo untuk mendapatkan semua informasi file Anda.

    FileInfo f = new FileInfo(@"C:\Hello\AnotherFolder\The File Name.PDF");
    MessageBox.Show(f.Name);
    MessageBox.Show(f.FullName);
    MessageBox.Show(f.Extension );
    MessageBox.Show(f.DirectoryName);
Blue Phoenix
sumber