Làm thế nào để có được tên tệp mà không có phần mở rộng trong Java?


Câu trả lời:


429

Nếu bạn, giống như tôi, thà sử dụng một số mã thư viện nơi họ có thể đã nghĩ đến tất cả các trường hợp đặc biệt, chẳng hạn như điều gì xảy ra nếu bạn chuyển thành null hoặc dấu chấm trong đường dẫn nhưng không phải trong tên tệp, bạn có thể sử dụng như sau:

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

61
bạn cũng có thể sử dụng FilenameUtils.getBasename để đi thẳng từ chuỗi đường dẫn đến tên tệp không có phần mở rộng.
Ian Durkan

2
Đơn giản nhất là tất nhiên là chạy maven :-) Nếu không, hãy xem: commons.apache.org/io
Ulf Lindback

8
Đối với những người thích ổi, nó cũng có thể làm điều này . (Những ngày này tôi không đích thân cảm thấy rất tốt về việc thêm Apache Commons phụ thuộc, mặc dù lịch sử những thư viện đã rất hữu ích.)
Jonik

3
Mặc dù Guava và Commons-IO có thể cung cấp thêm một chút, bạn sẽ ngạc nhiên khi có bao nhiêu phương thức tiện lợi đã được bao gồm trong JDK 7 với java.nio.file.FilesPath- chẳng hạn như giải quyết các thư mục cơ sở, sao chép / di chuyển tệp một dòng, chỉ nhận được tên tệp v.v.
Don Cheadle

3
@Lan Durkan hiện FilenameUtils.getBaseName có chữ N
Slow Harry

153

Cách dễ nhất là sử dụng một biểu thức thông thường.

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

Biểu thức trên sẽ xóa dấu chấm cuối cùng theo sau bởi một hoặc nhiều ký tự. Đây là một bài kiểm tra đơn vị cơ bản.

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

11
Regex không dễ sử dụng như giải pháp thư viện ở trên. Nó hoạt động, nhưng nhìn vào mã (mà không cần phải giải thích REGEX) không rõ ràng về những gì nó làm.
Gustavo Litovsky

5
@GustavoLitovsky Android không đi kèm với org.apache.commons. Theo như tôi biết, đây là cách duy nhất để làm điều đó trong Android.
Liam George Betsworth

1
/ * regex sau đây cũng xóa đường dẫn * / "/the/path/name.extension".replaceAll(".*[\\\\/[|\\.[ ^ \ \. [*" "," ") ;
daggett

1
Tôi sẽ thêm dấu gạch chéo vào lớp ký tự thứ hai để đảm bảo rằng bạn không bị vấp bởi một đường dẫn như "/foo/bar.x/baz"
chrisinmtown

53

Xem chương trình kiểm tra sau:

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

đầu ra nào:

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

Phần mở rộng của foo.tar.gzcái gì? Tôi có thể thấy tại sao .tar.gzsẽ là những gì bạn muốn.
tchrist

5
@tchrist, foo.tar.gzlà một phiên bản được nén bởi foo.tarvì vậy bạn cũng có thể tranh luận rằng đó gzlà phần mở rộng. Tất cả phụ thuộc vào cách bạn xác định phần mở rộng.
paxdiablo

2
Làm gì với tập tin như thế .gitignorenào?
michael nesterenko

như bạn đã biết tên lớp trong java không bao giờ nên bắt đầu bằng chữ nhỏ!
AnujKu

7
Nếu đó là một quy tắc, ngôn ngữ sẽ thực thi nó. Vì nó không phải, nó là một hướng dẫn, tuy nhiên, nó được đề xuất. Trong mọi trường hợp, điều đó hoàn toàn không liên quan đến câu hỏi và câu trả lời.
paxdiablo

47

Đây là thứ tự danh sách hợp nhất theo sở thích của tôi.

Sử dụng chung apache

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

Sử dụng Google Guava (Nếu bạn đã sử dụng nó)

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

Hoặc sử dụng 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 trọn đời

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

42

Nếu dự án của bạn sử dụng Guava (14.0 hoặc mới hơn), bạn có thể đi cùng Files.getNameWithoutExtension().

(Về cơ bản giống như FilenameUtils.removeExtension()từ Apache Commons IO, như câu trả lời được bình chọn cao nhất cho thấy. Tôi chỉ muốn chỉ ra rằng Guava cũng làm điều này. Cá nhân tôi không muốn thêm sự phụ thuộc vào Commons mà tôi cảm thấy là một chút của di tích. chỉ vì điều này.)


2
thực ra nó giống nhưFilenameUtils.getBaseName()
Angelo.Hannes

thực sự ổi là một lib không ổn định đến nỗi tôi chỉ cần tránh sử dụng nó bất cứ nơi nào tôi có thể. thích một di tích ổn định hơn các thí nghiệm của googel
Slava

8

Dưới đây là tài liệu tham khảo từ https://android.googlesource.com/pl platform / tools / tefefedutions / + / master / src / com / android / tefefed /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
Thông tin hay, nhưng người dùng, hãy lưu ý đối với các trường hợp như ".htaccess", trong đó phương thức này sẽ trả về "".
Markus Schulte

6

Nếu bạn không muốn nhập đầy đủ apache.commons, tôi đã trích xuất cùng chức năng:

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

Mặc dù tôi là một người tin tưởng lớn trong việc sử dụng lại các thư viện, nhưng org.apache.commons.io JAR là 174KB, rất lớn đối với một ứng dụng di động.

Nếu bạn tải xuống mã nguồn và xem lớp FilenameUtils của họ, bạn có thể thấy có rất nhiều tiện ích bổ sung và nó phù hợp với các đường dẫn Windows và Unix, tất cả đều đáng yêu.

Tuy nhiên, nếu bạn chỉ muốn một vài phương thức tiện ích tĩnh để sử dụng với các đường dẫn kiểu Unix (với dấu phân cách "/"), bạn có thể thấy mã dưới đây hữu ích.

Các removeExtensionphương pháp bảo quản phần còn lại của con đường cùng với tên tập tin. Cũng có một tương tự 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

Cách đơn giản nhất để lấy tên từ đường dẫn tương đối hoặc đường dẫn đầy đủ đang sử dụng

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


0

Bạn có thể chia nó bằng "." và trên chỉ mục 0 là tên tệp và trên 1 là phần mở rộng, nhưng tôi sẽ nghiêng về giải pháp tốt nhất với FileNameUtils từ apache.commons-io giống như nó đã được đề cập trong bài viết đầu tiên. Nó không phải được gỡ bỏ, nhưng hiệu quả là:

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


0

Sử dụng FilenameUtils.removeExtensiontừ Apache Commons IO

Thí dụ:

Bạn có thể cung cấp tên đường dẫn đầy đủ hoặc chỉ tên tệp .

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

Hi vọng điêu nay co ich ..


Điều đó đã có trong câu trả lời được chấp nhận, điểm của bài đăng này là gì?
Tom

0

Cách lưu loát:

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

0

Để đơn giản, hãy sử dụng phương thức String.replaceAll () của Java như sau:

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

Điều này cũng hoạt động khi fileNameWithExt bao gồm đường dẫn đủ điều kiện.


0

Bạn có thể sử dụng chức năng phân tách java để tách tên tệp khỏi tiện ích mở rộng, nếu bạn chắc chắn chỉ có một dấu chấm trong tên tệp dành cho tiện ích mở rộng.

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

do đó, split[0]sẽ trả về "test" và split [1] sẽ trả về "txt"


-3

Hãy thử mã dưới đây. Sử dụng các hàm cơ bản của Java. Nó chăm sóc Strings với phần mở rộng và không có phần mở rộng (không có '.'ký tự). Các trường hợp của nhiều '.'cũng được bảo hiểm.

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

Bạn có thể điều chỉnh nó để làm việc với các nullchuỗi.


1
Đó là thực tế khá xấu để tự thực hiện loại chức năng này. Thoạt nhìn, nhiệm vụ có vẻ cực kỳ rõ ràng , nhưng trong thực tế, bạn sẽ phải đối mặt với rất nhiều tình huống đặc biệt (như không có .tên tệp, hoặc tệp là bản sao lưu và có tên như document.docx.backup, v.v.). Thật đáng tin cậy hơn nhiều khi sử dụng thư viện bên ngoài xử lý tất cả các tình huống đặc biệt này cho bạn.
ivstas

1
Mặt khác, thêm vào nhiều thư viện cho dự án của bạn sẽ làm cho nó lớn hơn. Vì vậy, những điều đơn giản như thế này có thể được thực hiện bởi chính bạn.
Nicolas Tyler

1
Không có cách nào bạn nên tự làm điều này. Điều này thật khó: các tệp không có phần mở rộng nhưng. trong đường dẫn, đường dẫn ftp, cửa sổ và dấu gạch chéo, liên kết tượng trưng, ​​v.v ... Bạn chắc chắn sẽ thất bại và bằng cách cố gắng đạt được một chút bộ nhớ, bạn sẽ quảng cáo rất nhiều sự không ổn định. Ở mức tối thiểu sao chép các nguồn của mã được thiết lập nếu giấy phép cho phép nó.
Jonathan Nappee

Mã này trông giống như mã từ Amit Mishra, ngoại trừ điều đáng sợ 'if (! Str.contains ("."))'
Broken_Window

sẽ thất bại trong trường hợp sau "/someFolder/some.other.folder/someFileWithoutExtention". Điều đầu tiên xuất hiện trong tâm trí sau 2 giây .. tôi chắc chắn rằng tôi có thể đưa ra một tấn các ví dụ khác.
Newtopian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.