如何在Java中获取文件的文件扩展名?

时间:2010-08-26 00:19:38

标签: java file io

为了清楚起见,我不是在寻找MIME类型。

假设我有以下输入:/path/to/file/foo.txt

我想要一种方法来打破这种输入,特别是扩展到.txt。在Java中有没有内置的方法来做到这一点?我想避免编写自己的解析器。

31 个答案:

答案 0 :(得分:579)

在这种情况下,请使用FilenameUtils.getExtension

中的Apache Commons IO

以下是如何使用它的示例(您可以指定完整路径或仅指定文件名):

String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt"
String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe"

答案 1 :(得分:278)

你真的需要一个“解析器”吗?

String extension = "";

int i = fileName.lastIndexOf('.');
if (i > 0) {
    extension = fileName.substring(i+1);
}

假设您正在处理类似Windows的简单文件名,而不是像archive.tar.gz那样。

顺便说一下,对于目录可能有'。'但文件名本身没有(如/path/to.a/file)的情况,你可以做到

String extension = "";

int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));

if (i > p) {
    extension = fileName.substring(i+1);
}

答案 2 :(得分:89)

private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}

答案 3 :(得分:79)

如果您使用 Guava 库,则可以使用Files实用程序类。它有一个特定的方法,getFileExtension()。例如:

String path = "c:/path/to/file/foo.txt";
String ext = Files.getFileExtension(path);
System.out.println(ext); //prints txt

此外,您还可以获得具有类似功能的文件名getNameWithoutExtension()

String filename = Files.getNameWithoutExtension(path);
System.out.println(filename); //prints foo

答案 4 :(得分:28)

如果在Android上,您可以使用此功能:

String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());

答案 5 :(得分:15)

为了在点之前考虑没有字符的文件名,你必须使用接受答案的轻微变化:

String extension = "";

int i = fileName.lastIndexOf('.');
if (i >= 0) {
    extension = fileName.substring(i+1);
}

"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"

答案 6 :(得分:10)

这是一种经过测试的方法

public static String getExtension(String fileName) {
    char ch;
    int len;
    if(fileName==null || 
            (len = fileName.length())==0 || 
            (ch = fileName.charAt(len-1))=='/' || ch=='\\' || //in the case of a directory
             ch=='.' ) //in the case of . or ..
        return "";
    int dotInd = fileName.lastIndexOf('.'),
        sepInd = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
    if( dotInd<=sepInd )
        return "";
    else
        return fileName.substring(dotInd+1).toLowerCase();
}

测试用例:

@Test
public void testGetExtension() {
    assertEquals("", getExtension("C"));
    assertEquals("ext", getExtension("C.ext"));
    assertEquals("ext", getExtension("A/B/C.ext"));
    assertEquals("", getExtension("A/B/C.ext/"));
    assertEquals("", getExtension("A/B/C.ext/.."));
    assertEquals("bin", getExtension("A/B/C.bin"));
    assertEquals("hidden", getExtension(".hidden"));
    assertEquals("dsstore", getExtension("/user/home/.dsstore"));
    assertEquals("", getExtension(".strange."));
    assertEquals("3", getExtension("1.2.3"));
    assertEquals("exe", getExtension("C:\\Program Files (x86)\\java\\bin\\javaw.exe"));
}

答案 7 :(得分:10)

我的肮脏,可能最小的使用String.replaceAll

.replaceAll("^.*\\.(.*)$", "$1")

请注意,第一个*是贪婪的,因此它会尽可能地抓取大多数可能的字符,然后只剩下最后一个点和文件扩展名。

答案 8 :(得分:8)

从所有其他答案中可以明显看出,没有足够的“内置”功能。这是一种安全而简单的方法。

String getFileExtension(File file) {
    if (file == null) {
        return "";
    }
    String name = file.getName();
    int i = name.lastIndexOf('.');
    String ext = i > 0 ? name.substring(i + 1) : "";
    return ext;
}

答案 9 :(得分:6)

如何(使用Java 1.5 RegEx):

    String[] split = fullFileName.split("\\.");
    String ext = split[split.length - 1];

答案 10 :(得分:6)

如果您打算使用Apache commons-io,只想检查文件的扩展名然后进行一些操作,可以使用this,这是一个片段:

if(FilenameUtils.isExtension(file.getName(),"java")) {
    someoperation();
}

答案 11 :(得分:4)

JFileChooser怎么样?这并不简单,因为您需要解析其最终输出......

JFileChooser filechooser = new JFileChooser();
File file = new File("your.txt");
System.out.println("the extension type:"+filechooser.getTypeDescription(file));

这是一种MIME类型......

好的......我忘了你不想知道它的MIME类型。

以下链接中的有趣代码: http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html

/*
 * Get the extension of a file.
 */  
public static String getExtension(File f) {
    String ext = null;
    String s = f.getName();
    int i = s.lastIndexOf('.');

    if (i > 0 &&  i < s.length() - 1) {
        ext = s.substring(i+1).toLowerCase();
    }
    return ext;
}

相关问题: How do I trim a file extension from a String in Java?

答案 12 :(得分:4)

这是一个正确处理.tar.gz的方法,即使在目录名中带点的路径中也是如此:

private static final String getExtension(final String filename) {
  if (filename == null) return null;
  final String afterLastSlash = filename.substring(filename.lastIndexOf('/') + 1);
  final int afterLastBackslash = afterLastSlash.lastIndexOf('\\') + 1;
  final int dotIndex = afterLastSlash.indexOf('.', afterLastBackslash);
  return (dotIndex == -1) ? "" : afterLastSlash.substring(dotIndex + 1);
}
创建

afterLastSlash是为了更快地查找afterLastBackslash,因为如果有一些斜杠,它就不必搜索整个字符串。

原始char[]中的String会被重复使用,不会在那里添加垃圾,the JVM will probably notice that afterLastSlash is immediately garbage in order to put it on the stack instead of the heap

答案 13 :(得分:3)

这是Java 8的另一种形式。

String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)

它的工作原理如下:

  1. 使用“。”将字符串拆分为字符串数组。
  2. 将数组转换为流
  3. 使用reduce来获取流的最后一个元素,即文件扩展名

答案 14 :(得分:3)

String path = "/Users/test/test.txt"

String extension = path.substring(path.lastIndexOf("."), path.length());

返回&#34; .txt&#34;

如果您只想&#34; txt&#34;,请path.lastIndexOf(".") + 1

答案 15 :(得分:3)

如果您在项目中使用Spring框架,则可以使用StringUtils

import org.springframework.util.StringUtils;

StringUtils.getFilenameExtension("YourFileName")

答案 16 :(得分:2)

以下是带有Optional作为返回值的版本(因为您无法确定文件是否有扩展名)...还有完整性检查......

"/"

答案 17 :(得分:2)

如何 REGEX 版本:

static final Pattern PATTERN = Pattern.compile("(.*)\\.(.*)");

Matcher m = PATTERN.matcher(path);
if (m.find()) {
    System.out.println("File path/name: " + m.group(1));
    System.out.println("Extention: " + m.group(2));
}

或支持null扩展名:

static final Pattern PATTERN =
    Pattern.compile("((.*\\" + File.separator + ")?(.*)(\\.(.*)))|(.*\\" + File.separator + ")?(.*)");

class Separated {
    String path, name, ext;
}

Separated parsePath(String path) {
    Separated res = new Separated();
    Matcher m = PATTERN.matcher(path);
    if (m.find()) {
        if (m.group(1) != null) {
            res.path = m.group(2);
            res.name = m.group(3);
            res.ext = m.group(5);
        } else {
            res.path = m.group(6);
            res.name = m.group(7);
        }
    }
    return res;
}


Separated sp = parsePath("/root/docs/readme.txt");
System.out.println("path: " + sp.path);
System.out.println("name: " + sp.name);
System.out.println("Extention: " + sp.ext);

* nix的结果:
路径:/ root / docs /
名称:自述文件 延伸:txt

用于windows,parsePath(&#34; c:\ windows \ readme.txt&#34;):
路径:c:\ windows \
名称:自述文件 延伸:txt

答案 18 :(得分:2)

// Modified from EboMike's answer

String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));
运行时,

扩展名应包含“.txt”。

答案 19 :(得分:1)

不使用任何库,可以使用String方法拆分如下:

        String[] splits = fileNames.get(i).split("\\.");

        String extension = "";

        if(splits.length >= 2)
        {
            extension = splits[splits.length-1];
        }

答案 20 :(得分:1)

这里我做了一个小方法(但不是那么安全并且没有检查很多错误),但如果只是你编写一个普通的java程序,这就足以找到文件类型了。这不适用于复杂的文件类型,但通常不会使用那些。

    public static String getFileType(String path){
       String fileType = null;
       fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase();
       return fileType;
}

答案 21 :(得分:1)

从文件名获取文件扩展名

/**
 * The extension separator character.
 */
private static final char EXTENSION_SEPARATOR = '.';

/**
 * The Unix separator character.
 */
private static final char UNIX_SEPARATOR = '/';

/**
 * The Windows separator character.
 */
private static final char WINDOWS_SEPARATOR = '\\';

/**
 * The system separator character.
 */
private static final char SYSTEM_SEPARATOR = File.separatorChar;

/**
 * Gets the extension of a filename.
 * <p>
 * This method returns the textual part of the filename after the last dot.
 * There must be no directory separator after the dot.
 * <pre>
 * foo.txt      --> "txt"
 * a/b/c.jpg    --> "jpg"
 * a/b.txt/c    --> ""
 * a/b/c        --> ""
 * </pre>
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename the filename to retrieve the extension of.
 * @return the extension of the file or an empty string if none exists.
 */
public static String getExtension(String filename) {
    if (filename == null) {
        return null;
    }
    int index = indexOfExtension(filename);
    if (index == -1) {
        return "";
    } else {
        return filename.substring(index + 1);
    }
}

/**
 * Returns the index of the last extension separator character, which is a dot.
 * <p>
 * This method also checks that there is no directory separator after the last dot.
 * To do this it uses {@link #indexOfLastSeparator(String)} which will
 * handle a file in either Unix or Windows format.
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename  the filename to find the last path separator in, null returns -1
 * @return the index of the last separator character, or -1 if there
 * is no such character
 */
public static int indexOfExtension(String filename) {
    if (filename == null) {
        return -1;
    }
    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
    int lastSeparator = indexOfLastSeparator(filename);
    return (lastSeparator > extensionPos ? -1 : extensionPos);
}

/**
 * Returns the index of the last directory separator character.
 * <p>
 * This method will handle a file in either Unix or Windows format.
 * The position of the last forward or backslash is returned.
 * <p>
 * The output will be the same irrespective of the machine that the code is running on.
 *
 * @param filename  the filename to find the last path separator in, null returns -1
 * @return the index of the last separator character, or -1 if there
 * is no such character
 */
public static int indexOfLastSeparator(String filename) {
    if (filename == null) {
        return -1;
    }
    int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
    int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
    return Math.max(lastUnixPos, lastWindowsPos);
}

<强>积分

  1. 从Apache FileNameUtils类复制 - http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.3.2/org/apache/commons/io/FilenameUtils.java#FilenameUtils.getExtension%28java.lang.String%29

答案 22 :(得分:1)

String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");

答案 23 :(得分:0)

这个特别的问题给我带来了很多麻烦,然后我找到了一个非常简单的解决方案,我在这里发布了这个问题。

file.getName().toLowerCase().endsWith(".txt");

那就是它。

答案 24 :(得分:0)

我找到了一种更好的方法,通过混合以上所有答案来找到扩展

public static String getFileExtension(String fileLink) {

        String extension;
        Uri uri = Uri.parse(fileLink);
        String scheme = uri.getScheme();
        if (scheme != null && scheme.equals(ContentResolver.SCHEME_CONTENT)) {
            MimeTypeMap mime = MimeTypeMap.getSingleton();
            extension = mime.getExtensionFromMimeType(CoreApp.getInstance().getContentResolver().getType(uri));
        } else {
            extension = MimeTypeMap.getFileExtensionFromUrl(fileLink);
        }

        return extension;
    }

public static String getMimeType(String fileLink) {
        String type = CoreApp.getInstance().getContentResolver().getType(Uri.parse(fileLink));
        if (!TextUtils.isEmpty(type)) return type;
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        return mime.getMimeTypeFromExtension(FileChooserUtil.getFileExtension(fileLink));
    }

答案 25 :(得分:0)

我喜欢spectre's answer的简单性,在他的一个评论中链接的是指向另一个答案的链接,该答案可以解决另一个问题made by EboMike上文件路径中的点。

在不实现某种第三方API的情况下,我建议:

private String getFileExtension(File file) {

    String name = file.getName().substring(Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')) < 0 ? 0 : Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')));
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf + 1); // doesn't return "." with extension
}

例如any of ImageIO's write methods这类必须传递文件格式的东西可能会有用。

为什么可以自己动手使用整个第三方API?

答案 26 :(得分:0)

只是基于正则表达式的替代方案。不是那么快,不是那么好。

Pattern pattern = Pattern.compile("\\.([^.]*)$");
Matcher matcher = pattern.matcher(fileName);

if (matcher.find()) {
    String ext = matcher.group(1);
}

答案 27 :(得分:0)

    private String getExtension(File file)
        {
            String fileName = file.getName();
            String[] ext = fileName.split("\\.");
            return ext[ext.length -1];
        }

答案 28 :(得分:-1)

试试这个。

String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg

答案 29 :(得分:-1)

  @Test
    public void getFileExtension(String fileName){
      String extension = null;
      List<String> list = new ArrayList<>();
      do{
          extension =  FilenameUtils.getExtension(fileName);
          if(extension==null){
              break;
          }
          if(!extension.isEmpty()){
              list.add("."+extension);
          }
          fileName = FilenameUtils.getBaseName(fileName);
      }while (!extension.isEmpty());
      Collections.reverse(list);
      System.out.println(list.toString());
    }

答案 30 :(得分:-4)

Java在java.nio.file.Files class中有一种内置的处理方式,可以满足您的需求:

File f = new File("/path/to/file/foo.txt");
String ext = Files.probeContentType(f.toPath());
if(ext.equalsIgnoreCase("txt")) do whatever;

请注意,此静态方法使用规范found here来检索“内容类型”,这可能会有所不同。