如何在Java中获得没有扩展名的文件名?

如何在Java中获得没有扩展名的文件名?,java,file,Java,File,有人能告诉我如何获得没有扩展名的文件名吗? 例如: 请参阅以下测试程序: public class javatemp { static String stripExtension (String str) { // Handle null case specially. if (str == null) return null; // Get position of last '.'. int pos = str.la

有人能告诉我如何获得没有扩展名的文件名吗? 例如:


请参阅以下测试程序:

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
测试->测试
测试。->测试

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

fileNameWithOutExt = "test.xml".replaceFirst("[.][^.]+$", "");
上面的表达式将删除最后一个点,后跟一个或多个字符。这里有一个基本的单元测试

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

如果您和我一样,更愿意使用一些库代码,其中他们可能考虑了所有特殊情况,例如如果传入null或路径中的点而不是文件名中的点,则可以使用以下代码:

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

虽然我非常相信重用库,但它的容量是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;
}

请尝试下面的代码。使用核心Java基本函数。它负责带扩展名和不带扩展名的
字符串。
字符。还包括多个
”的情况。

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
字符串。

如果您的项目使用(14.0或更新版本),您可以使用


(本质上与Apache Commons IO中的
FilenameUtils.removeExtension()
相同。我只是想指出,Guava也会这样做。就我个人而言,我不想添加对Commons的依赖性,因为我觉得这有点过时。)

这是我喜欢的合并列表顺序

使用apache commons

import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);
                          
                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);
使用谷歌番石榴(如果你已经在使用它)

或使用核心Java

(一)

  • 以下为参考资料

    /**
    *获取给定文件名的基名称(不带扩展名)。
    *

    *例如,getBaseName(“file.txt”)将返回“file” * *@param文件名 *@返回基名称 */ 公共静态字符串getBaseName(字符串文件名){ int index=fileName.lastIndexOf('.'); 如果(索引==-1){ 返回文件名; }否则{ 返回fileName.substring(0,索引); } }


    如果您不想导入完整的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;
            }
        }
    }
    
    您可以将其按“.”拆分,索引0上的是文件名,索引1上的是扩展名,但我倾向于使用apache.commons-io中的FileNameUtils寻找最佳解决方案,就像第一篇文章中提到的那样。无需移除,但只需:


    String fileName=FilenameUtils.getBaseName(“test.xml”)

    使用
    FilenameUtils.removeExtension
    Apache Commons IO

    例如:

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

    String myString1 = FilenameUtils.removeExtension("helloworld.exe"); // returns "helloworld"
    String myString2 = FilenameUtils.removeExtension("/home/abc/yey.xls"); // returns "yey"
    
    希望这有助于..

    流畅的方式:

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

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

    import org.apache.commons.io.FilenameUtils;
    FilenameUtils.getBaseName(定义文件路径)
    

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

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

    当fileNameWithExt包含完全限定路径时,这也适用。

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

    File filename=新文件('test.txt');
    File.getName().split(“[.]”)


    因此,
    split[0]
    将返回“test”,split[1]将返回“txt”

    我的解决方案需要以下导入

    import java.io.File;
    
    以下方法应返回所需的输出字符串:

    private static String getFilenameWithoutExtension(File file) throws IOException {
        String filename = file.getCanonicalPath();
        String filenameWithoutExtension;
        if (filename.contains("."))
            filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1, filename.lastIndexOf('.'));
        else
            filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1);
    
        return filenameWithoutExtension;
    }
    

    对于Kotlin来说,它现在很简单:

    val fileNameStr = file.nameWithoutExtension
    

    您还可以使用FilenameUtils.getBasename直接从路径字符串转到文件名,而不带扩展名。最简单的方法当然是运行maven:-)否则,请参见:对于喜欢Guava的人。(最近我个人对添加Apache Commons依赖项感觉不太好,尽管从历史上看,这些库非常有用。)虽然Guava和Commons IO可能会提供一些额外的功能,您会惊讶地发现,JDK 7中已经包含了许多方便的方法,包括
    java.nio.file.Files
    Path
    ——例如解析基本目录、一行复制/移动文件,仅获取文件名等@Lan Durkan当前FilenameUtils.getBaseName,大写字母为nw
    foo.tar.gz
    的扩展名是什么?我明白为什么
    .tar.gz
    会是你想要的。@tchrist,
    foo.tar.gz
    foo.tar
    的压缩版本,所以你也可以说
    gz
    是扩展。这一切都取决于您如何定义扩展名。如何处理
    .gitignore
    之类的文件?正如您所知,java中的类名永远不能以小写字母开头!如果这是一条规则,语言将强制执行它。因为它不是,所以无论建议的力度有多大,它都是一个指南。无论如何,这与问题和答案完全无关。Regex不像上面的库解决方案那么容易使用。它可以工作,但是查看代码(不必解释正则表达式)并不明显。@GustavoLitovsky Android没有附带
    org.apache.commons
    。据我所知,这是在Android中实现这一点的唯一方法。/*下面的正则表达式还删除了path*/“/the/path/name.extension.replaceAll(“.[\\\\/]\.\.\\.]*$”,”);我会在第二个字符类中添加斜线,以确保不会被pa绊倒
    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;
            }
        }
    }
    
    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("."));
        }
    
    String myString1 = FilenameUtils.removeExtension("helloworld.exe"); // returns "helloworld"
    String myString2 = FilenameUtils.removeExtension("/home/abc/yey.xls"); // returns "yey"
    
    public static String fileNameWithOutExt (String fileName) {
        return Optional.of(fileName.lastIndexOf(".")).filter(i-> i >= 0)
                .map(i-> fileName.substring(0, i)).orElse(fileName);
    }
    
    String fileNameWithExt = "test.xml";
    String fileNameWithoutExt
       = fileNameWithExt.replaceAll( "^.*?(([^/\\\\\\.]+))\\.[^\\.]+$", "$1" );
    
    import java.io.File;
    
    private static String getFilenameWithoutExtension(File file) throws IOException {
        String filename = file.getCanonicalPath();
        String filenameWithoutExtension;
        if (filename.contains("."))
            filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1, filename.lastIndexOf('.'));
        else
            filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1);
    
        return filenameWithoutExtension;
    }
    
    val fileNameStr = file.nameWithoutExtension