问答中心分类: JAVA如何在 Java 中获取文件的文件扩展名?
0
匿名用户 提问 24分钟 前

为了清楚起见,我不是在寻找 MIME 类型。
假设我有以下输入:/path/to/file/foo.txt
我想要一种方法来分解这个输入,特别是.txt为扩展。在 Java 中有没有内置的方法来做到这一点?我想避免编写自己的解析器。

ArtOfWarfare 回复 24分钟 前

你永远不知道什么时候会出现一些将扩展定义为用逗号分隔的新平台。现在您需要编写平台相关的代码。 Java 框架应该更具前瞻性,并具有用于获取扩展的 API,它们编写依赖于平台的代码,而作为 API 的用户,您只需说获取扩展。

ArtOfWarfare 回复 24分钟 前

@ArtOfWarfare:天啊。让我们创建一个包含数千个类的 100MB JRE,但请确保不要实现任何返回的方法"txt""filename.txt"因为某处的某个平台可能想要使用"filename,txt".

ArtOfWarfare 回复 24分钟 前

@EricDuminil“确保不实现任何从“filename.txt”返回“txt”的方法”???尝试path.substring(path.lastIndexOf("."));…..是的..他们肯定不会白白复制一些东西…

ArtOfWarfare 回复 24分钟 前

@VelocityPulse 那是确切地有什么困扰我。由于没有获取文件扩展名的标准方法,因此您会得到几十个半错误的答案和略有不同的实现。您的代码使用 2 种方法(我本来希望有单个显式方法),它返回".txt""filename.txt",这可能不是想要的结果,最糟糕的是,它失败了StringIndexOutOfBoundsException如果没有扩展名,而不是返回空字符串。

28 Answers
0
EboMike 回答 24分钟 前

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

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);
}
longda 回复 24分钟 前

谢谢!当然,您可能需要一个解析器/对象,如果您想做更多的操作而不仅仅是扩展名……说如果您只想要路径、父目录、文件名(减去扩展名)等。我m 来自 C# 和 .Net,我们有这个:msdn.microsoft.com/en-us/library/…

Tyler 回复 24分钟 前

正如您所说,除了使用简单的 lastIndexOf(“.”) 之外,还有很多事情需要考虑。我猜想 Apache Commons 有一种方法可以解决这个问题,它考虑了所有棘手的潜在问题。

Pijusn 回复 24分钟 前

我认为i > 0应该改为i >= 0或者i != -1.这会处理文件名,例如.htaccess.

longda 回复 24分钟 前

我上面评论中的新 MSDN 链接:msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

foolo 回复 24分钟 前

如果文件扩展名包含反斜杠,此解决方案将失败。

Don Cheadle 回复 24分钟 前

不管任何代码片段多么简单……你仍然需要更新它/维护它/测试它/使它作为一个方便的依赖项可用……如果已经有一个库来完成所有这些工作会容易得多

tgkprog 回复 24分钟 前

更多问题是文件是否以点结尾。在库中更好。 if (i > p && i < (fileName.length()-1)) { extension = fileName.substring(i+1);

Dávid Horváth 回复 24分钟 前

你应该使用File.separatorChar代替/[backslash].

user1156544 回复 24分钟 前

int i = filename.lastIndexOf('.')给出一个dereferencing possible null pointerNetbeans 上的警告。这是为什么?

stackexchanger 回复 24分钟 前

@user1156544 因为如果没有.它会给出一个空指针异常(使用库的另一个原因)

Josh M. 回复 24分钟 前

“你真的需要一个“解析器”吗?”当Java(通常)根本不包含API中的明显内容时,就会出现这种类型的问题。比如怎么样new File(filename).getExtension()——那会很酷。

0
luke1985 回答 24分钟 前
private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}
NickEntin 回复 24分钟 前

需要注意的是,这会返回’.’。同样,因此您的文件扩展名将是“.txt”,而不是其他一些答案中的“txt”

Hanzallah Afgan 回复 24分钟 前

更好的答案和@NickEntin 更好的评论。删除句点“.”从文件的扩展名来看,可以编码为 int lastIndexOf = name.lastIndexOf(“.”) + 1;

Iman Akbari 回复 24分钟 前

这种方法在某些情况下可能不起作用,例如 /usr/bin/foo.bar/httpconf

Iman Akbari 回复 24分钟 前

@lukasz1985 1. 数百个 linux 软件包使用“init.d”之类的名称创建目录,此外,依赖没有带点的目录的路径是不安全的,因为它不是非法的 2. 我正在为 Android 编码,所以我使用了一些 SDK方法我不记得了,但我猜stackoverflow.com/a/3571239/2546146没有这个缺陷

Erdal G. 回复 24分钟 前

@luke1985 所有 GitHub 的存储库都以 .git 结尾,但它们实际上是文件夹 🙂

Dreamspace President 回复 24分钟 前

@Iman Akbari: getName() 仅返回文件名本身,在您的示例中为“httpconf”。

intrepidis 回复 24分钟 前

您不应该依赖异常来防范草率的编码。这里不需要异常处理。

Radiodef 回复 24分钟 前

添加的编辑+ 1当文件名没有扩展名时无意中引入了不正确的行为。在像这样的情况下"abc"该方法应该返回""但是编辑使它错误地返回"abc".我将答案退回到 Ilya 的修订版,因为它是最好的示例代码,并且答案的原作者(出于某种原因更喜欢异常)是不活跃的。

0
JeanValjean 回答 24分钟 前

如果你使用番石榴图书馆,你可以求助于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
JeanValjean 回复 24分钟 前

真的吗?这是一个很棒的图书馆,里面有很多实用工具。他们中的大多数将成为 Java8 的一部分,就像伟大的 GuavaFunction.

Lluis Martinez 回复 24分钟 前

不幸的是,并非所有人都可以决定使用哪些库。至少我们有 Apache Commons,尽管它很旧。

Al-Mothafar 回复 24分钟 前

如果你看到源代码getFileExtension实际上它只是int dotIndex = fileName.lastIndexOf('.'); return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1)所以没什么大不了的。另外,请注意Files由于某种原因被标记为“不稳定”。

JeanValjean 回复 24分钟 前

@Al-Mothafar 很多类都被标记为不稳定的(请参阅多地图构建器),我也不明白为什么:已经发布了几个,但那里没有任何改变。

0
intrepidis 回答 24分钟 前

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

String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
Ahmad 回复 24分钟 前

除了英语之外,它没有得到扩展

0
yavuzkavus 回答 24分钟 前

这是一种经过测试的方法

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