简体   繁体   English

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

[英]How do I get the file extension of a file in Java?

Just to be clear, I'm not looking for the MIME type.为了清楚起见,我不是在寻找 MIME 类型。

Let's say I have the following input: /path/to/file/foo.txt假设我有以下输入: /path/to/file/foo.txt

I'd like a way to break this input up, specifically into .txt for the extension.我想要一种方法来分解这个输入,特别是扩展到.txt中。 Is there any built in way to do this in Java?在 Java 中是否有任何内置方法可以做到这一点? I would like to avoid writing my own parser.我想避免编写自己的解析器。

In this case, use FilenameUtils.getExtension from Apache Commons IO在这种情况下,请使用Apache Commons IO 中的FilenameUtils.getExtension

Here is an example of how to use it (you may specify either full path or just file name):以下是如何使用它的示例(您可以指定完整路径或仅指定文件名):

import org.apache.commons.io.FilenameUtils;

// ...

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

Maven dependency: Maven 依赖:

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

Gradle Groovy DSL Gradle Groovy DSL

implementation 'commons-io:commons-io:2.6'

Gradle Kotlin DSL Gradle Kotlin DSL

implementation("commons-io:commons-io:2.6")

Othershttps://search.maven.org/artifact/commons-io/commons-io/2.6/jar其他https://search.maven.org/artifact/commons-io/commons-io/2.6/jar

Do you really need a "parser" for this?你真的需要一个“解析器”吗?

String extension = "";

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

Assuming that you're dealing with simple Windows-like file names, not something like archive.tar.gz .假设您正在处理类似 Windows 的简单文件名,而不是类似archive.tar.gz文件名。

Btw, for the case that a directory may have a '.', but the filename itself doesn't (like /path/to.a/file ), you can do顺便说一句,对于目录可能有“.”的情况,但文件名本身没有(如/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);
}
private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}

If you use Guava library, you can resort to Files utility class.如果您使用Guava库,则可以求助于Files实用程序类。 It has a specific method, getFileExtension() .它有一个特定的方法, getFileExtension() For instance:例如:

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

In addition you may also obtain the filename with a similar function, getNameWithoutExtension() :此外,您还可以使用类似的函数getNameWithoutExtension()获取文件名:

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

如果在 Android 上,你可以使用这个:

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

This is a tested method这是一个经过测试的方法

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

And test case:和测试用例:

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

In order to take into account file names without characters before the dot, you have to use that slight variation of the accepted answer:为了考虑点没有字符的文件名,您必须使用已接受答案的细微变化:

String extension = "";

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

"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"
String path = "/Users/test/test.txt";
String extension = "";

if (path.contains("."))
     extension = path.substring(path.lastIndexOf("."));

return ".txt"返回“.txt”

if you want only "txt", make path.lastIndexOf(".") + 1如果您只想要“txt”,请制作path.lastIndexOf(".") + 1

My dirty and may tiniest using String.replaceAll :使用String.replaceAll 时,我的脏东西可能是最小的:

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

Note that first * is greedy so it will grab most possible characters as far as it can and then just last dot and file extension will be left.请注意,第一个*是贪婪的,因此它会尽可能地抓取大多数可能的字符,然后只剩下最后一个点和文件扩展名。

As is obvious from all the other answers, there's no adequate "built-in" function.从所有其他答案中可以明显看出,没有足够的“内置”功能。 This is a safe and simple method.这是一种安全且简单的方法。

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

If you use Spring framework in your project, then you can use StringUtils如果您在项目中使用 Spring 框架,那么您可以使用StringUtils

import org.springframework.util.StringUtils;

StringUtils.getFilenameExtension("YourFileName")

How about (using Java 1.5 RegEx):怎么样(使用 Java 1.5 RegEx):

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

Here is another one-liner for Java 8.这是 Java 8 的另一个单行代码。

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

It works as follows:它的工作原理如下:

  1. Split the string into an array of strings using "."使用“.”将字符串拆分为字符串数组。
  2. Convert the array into a stream将数组转换为流
  3. Use reduce to get the last element of the stream, ie the file extension使用reduce获取流的最后一个元素,即文件扩展名

If you plan to use Apache commons-io,and just want to check the file's extension and then do some operation,you can use this ,here is a snippet:如果您打算使用Apache commons-io,并且只想检查文件的扩展名然后进行一些操作,您可以使用,这里是一个片段:

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

Here's a method that handles .tar.gz properly, even in a path with dots in directory names:这是一种正确处理.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 is created to make finding afterLastBackslash quicker since it won't have to search the whole string if there are some slashes in it.创建afterLastSlash是为了更快地找到afterLastBackslash因为如果其中有一些斜线,它就不必搜索整个字符串。

The char[] inside the original String is reused, adding no garbage there, and the JVM will probably notice that afterLastSlash is immediately garbage in order to put it on the stack instead of the heap .原始Stringchar[]被重用,没有在那里添加垃圾, JVM 可能会注意到afterLastSlash立即是垃圾,以便将它放在堆栈而不是堆上

How about JFileChooser? JFileChooser 怎么样? It is not straightforward as you will need to parse its final output...这并不简单,因为您需要解析其最终输出...

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

which is a MIME type...这是一种 MIME 类型...

OK...I forget that you don't want to know its MIME type.好吧...我忘了你不想知道它的 MIME 类型。

Interesting code in the following link: http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html以下链接中的有趣代码: 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;
}

Related question: How do I trim a file extension from a String in Java?相关问题: 如何从 Java 中的字符串修剪文件扩展名?

// Modified from EboMike's answer

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

extension should have ".txt" in it when run.运行时扩展名应该包含“.txt”。

This particular question gave me a lot of trouble then i found a very simple solution for this problem which i'm posting here.这个特定的问题给我带来了很多麻烦然后我找到了一个非常简单的解决方案,我在这里发布。

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

That's it.就是这样。

How about REGEX version:正则表达式版本怎么样:

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

or with null extension supported:或支持空扩展名:

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

result for *nix: *nix 的结果:
path: /root/docs/路径:/root/docs/
name: readme名称:自述
Extention: txt扩展名:.txt

for windows, parsePath("c:\\windows\\readme.txt"):对于 Windows, parsePath("c:\\windows\\readme.txt"):
path: c:\\windows\\路径:c:\\windows\\
name: readme名称:自述
Extention: txt扩展名:.txt

Here's the version with Optional as a return value (cause you can't be sure the file has an extension)... also sanity checks...这是带有 Optional 作为返回值的版本(因为您无法确定文件是否具有扩展名)......还有健全性检查......

import java.io.File;
import java.util.Optional;

public class GetFileExtensionTool {

    public static Optional<String> getFileExtension(File file) {
        if (file == null) {
            throw new NullPointerException("file argument was null");
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("getFileExtension(File file)"
                    + " called on File object that wasn't an actual file"
                    + " (perhaps a directory or device?). file had path: "
                    + file.getAbsolutePath());
        }
        String fileName = file.getName();
        int i = fileName.lastIndexOf('.');
        if (i > 0) {
            return Optional.of(fileName.substring(i + 1));
        } else {
            return Optional.empty();
        }
    }
}
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");

Here I made a small method (however not that secure and doesnt check for many errors), but if it is only you that is programming a general java-program, this is more than enough to find the filetype.在这里我做了一个小方法(但不是那么安全并且不会检查很多错误),但如果只有你在编写一个通用的java程序,这足以找到文件类型。 This is not working for complex filetypes, but those are normally not used as much.这不适用于复杂的文件类型,但通常不会使用那么多。

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

Getting File Extension from File Name从文件名获取文件扩展名

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

Credits学分

  1. Copied from Apache FileNameUtils Class - 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从 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

Without use of any library, you can use the String method split as follows :在不使用任何库的情况下,您可以使用 String 方法 split 如下:

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

        String extension = "";

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

Just a regular-expression based alternative.只是一个基于正则表达式的替代方案。 Not that fast, not that good.没那么快,也没那么好。

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

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

I like the simplicity of spectre's answer , and linked in one of his comments is a link to another answer that fixes dots in file paths, on another question, made by EboMike .我喜欢Spectre 的简单回答,并且在他的一个评论中链接了指向另一个答案的链接,该答案修复了 EboMike在另一个问题上的文件路径中的点。

Without implementing some sort of third party API, I suggest:在不实施某种第三方 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
}

Something like this may be useful in, say, any of ImageIO's write methods , where the file format has to be passed in.像这样的东西可能在ImageIO 的任何write方法中很有用,其中必须传入文件格式。

Why use a whole third party API when you can DIY?当您可以 DIY 时,为什么要使用完整的第三方 API?

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

try this.尝试这个。

String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg
  @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());
    }

I found a better way to find extension by mixing all above answers我找到了一种通过混合上述所有答案来找到扩展名的更好方法

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

Just to be clear, I'm not looking for the MIME type.为了清楚起见,我不是在寻找MIME类型。

Let's say I have the following input: /path/to/file/foo.txt假设我输入以下内容: /path/to/file/foo.txt

I'd like a way to break this input up, specifically into .txt for the extension.我想要一种分解此输入的方法,特别是将扩展名分解为.txt Is there any built in way to do this in Java?有没有内置的方法可以用Java做到这一点? I would like to avoid writing my own parser.我想避免编写自己的解析器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何解析 URL 路径,获取文件名,然后使用 JSTL 和 Java scriptlet 替换文件扩展名 - How do I parse through a URL path, get the filename, then replace the file extension using JSTL and Java scriptlet 如何从 Java 中的字符串修剪文件扩展名? - How do I trim a file extension from a String in Java? 如何将Java资源作为文件获取? - How do I get a Java resource as a File? 如何在 android Java 中获取文件名和扩展名 - How to get file name and extension in android Java 如何获取Java中没有扩展名的文件? - How to get a file without the extension in Java? 当我使用 java 从文件夹下载 Excel 时,出现此错误“.xls 文件的格式和扩展名不匹配。文件可能已损坏” - When I download Excel from a folder with java I get this error " the format and extension of the .xls file do not match. The file may be damaged" 如何获得文件扩展名? - How to get file extension? 如何使用Java获取网络驱动器文件系统对象 - How do I get a network drive File System object in Java 如何在OSX上获取Java文件所有者的名称? - How do I get the name of a file's owner in Java on OSX? 如何将文件中的字符转换为Java中的2D数组? - How do i get characters in a file into a 2D array in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM