如何在Java中不带扩展名的文件名?


Answers:


429

如果您像我一样,宁愿使用某些可能考虑了所有特殊情况的库代码,例如,如果在路径中输入null或点而不在文件名中输入时会发生什么,则可以使用以下代码:

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

61
您还可以使用FilenameUtils.getBasename直接从路径字符串转到没有扩展名的文件名。
伊恩·杜肯

2
最简单的当然是运行maven :-)否则,请参见:commons.apache.org/io
Ulf Lindback

8
对于那些喜欢番石榴的人,它也可以这样做。(这些天来,我个人对添加Apache Commons依赖项并不满意,尽管从历史上看,这些库非常有用。)
Jonik

3
虽然番石榴和共享-IO可以提供一些额外的,你会惊奇地发现许多方便的方法都已经包含在JDK 7java.nio.file.FilesPath-如解决基础目录,一个行复制/移动文件时,只得到文件名等
Don Cheadle

3
@Lan Durkan当前使用大写字母N的FilenameUtils.getBaseName
Slow Harry

153

最简单的方法是使用正则表达式。

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

上面的表达式将删除最后一个点,后跟一个或多个字符。这是一个基本的单元测试。

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

11
正则表达式不像上面的库解决方案那样易于使用。它可以工作,但是查看代码(不必解释REGEX)并不明显。
古斯塔沃·利托夫斯基

5
@GustavoLitovsky Android未捆绑在一起org.apache.commons。据我所知,这是在Android中执行此操作的唯一方法。
Liam George Betsworth 2014年

1
/ *以下正则表达式也会删除路径* /“ /the/path/name.extension".replaceAll(".*[\\\\/]|\\.[^\\.]*$”,“”) ;
daggett

1
我会在第二个字符类中添加斜杠,以确保您不会被“ /foo/bar.x/baz”之类的路径绊倒
chrisinmtown

53

请参阅以下测试程序:

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

输出:

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

什么是扩展名foo.tar.gz?我知道为什么.tar.gz会是您想要的。
tchrist 2011年

5
@tchrist foo.tar.gz是gzip的压缩版本,foo.tar因此您也可以认为这gz是扩展名。一切都取决于您如何定义扩展。
paxdiablo 2011年

2
如何处理类似文件.gitignore
michael nesterenko

如您所知,java中的类名绝不能以小写字母开头!
2013年

7
如果这是规则,则该语言将强制执行。既然没有,那么无论如何它都是一个指导性建议。无论如何,这完全与问题和答案无关。
paxdiablo

47

这是我的偏好的合并列表顺序。

使用Apache Commons

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);

使用Google Guava(如果您已经使用过)

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

或使用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("");
}

Liferay API

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

42

如果您的项目使用的是Guava(14.0或更高版本),则可以使用Files.getNameWithoutExtension()

(基本上与FilenameUtils.removeExtension()Apache Commons IO 的相同,正如投票最高的答案所暗示的。只是想指出番石榴也这样做。正因为如此。)


2
实际上更像是FilenameUtils.getBaseName()
Angelo.Hannes

番石榴实际上是一个不稳定的库,我只是尽可能地避免使用它。比googel的实验更喜欢稳定的遗物
Slava

8

以下是来自https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/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
不错的信息,但用户请注意“ .htaccess”之类的情况,该方法将返回“”。
马库斯·舒尔特

6

如果您不喜欢导入完整的apache.commons,那么我提取了相同的功能:

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

虽然我坚信重用库,但是org.apache.commons.io JAR为174KB,对于移动应用程序而言,这显然很大。

如果下载源代码并查看其FilenameUtils类,则可以看到有很多其他实用程序,它确实可以处理Windows和Unix路径,这一切都很可爱。

但是,如果您只想使用几种静态实用程序方法来与Unix样式路径一起使用(带有“ /”分隔符),则可以发现下面的代码很有用。

removeExtension方法保留路径的其余部分以及文件名。也有相似之处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

从相对路径或完整路径获取名称的最简单方法是使用

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


0

您可以将其分隔为“。” 在索引0上是文件名,在索引1上是扩展名,但是我倾向于使用apache.commons-io的FileNameUtils来寻求最佳解决方案,就像在第一篇文章中提到的那样。它不必删除,但是足够了:

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


0

使用FilenameUtils.removeExtension来自Apache的百科全书IO

例:

您可以提供完整路径名提供文件名

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

希望这可以帮助 ..


那已经在接受的答案中了,这篇文章的目的是什么?
汤姆(Tom)

0

流利的方式:

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

0

为简单起见,请使用Java的String.replaceAll()方法,如下所示:

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

当fileNameWithExt包含标准路径时,该方法也适用。


0

如果您确定文件名中只有一个点可用于扩展名,则可以使用java split函数从扩展名中拆分文件名。

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

因此split[0]将会返回“测试”,split [1]将返回“ txt”


-3

试试下面的代码。使用核心Java基本功能。它照顾String带扩展名和不带扩展名(不带'.'字符)的。'.'也涵盖了多个情况。

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

您可以修改它以使用null字符串。


1
自己实现这种功能是非常不好的做法。乍一看,任务似乎非常明显,但是在实践中,您将面临许多特殊情况(例如.文件名中没有文件,或者文件是备份文件,并且具有类似的名称document.docx.backup,等等)。使用外部库为您处理所有这些特殊情况要可靠得多。
ivstas 2014年

1
另一方面,将许多库添加到您的项目中会使它更大。如此简单的事情可以自己完成。
Nicolas Tyler

1
您绝对不能自己这样做。这很难:文件扩展名为。在路径,ftp路径,windows和unix斜线,符号链接等...中,您肯定会失败,并且尝试获取一些内存会带来很多不稳定性。如果许可证允许,请至少复制已建立代码的来源。
乔纳森·纳皮

这段代码看起来像是阿米特·米什拉(Amit Mishra)的代码,除了令人生畏的'if(!str.contains(“。”))'
Broken_Window

在以下情况下将失败:“ / someFolder / some.other.folder / someFileWithoutExtention”。2秒钟后突然想到的第一件事..我敢肯定,我可以拿出很多其他例子。
Newtopian
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.