【问题标题】:How to get the filename without the extension in Java?如何在Java中获取没有扩展名的文件名?
【发布时间】:2010-10-29 19:00:17
【问题描述】:

谁能告诉我如何获取没有扩展名的文件名? 示例:

fileNameWithExt = "test.xml";
fileNameWithOutExt = "test";

【问题讨论】:

标签: java file


【解决方案1】:

如果您像我一样,宁愿在他们可能已经考虑到所有特殊情况的地方使用一些库代码,例如如果您传入 null 或路径中的点而不是路径中的点会发生什么文件名,您可以使用以下内容:

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

【讨论】:

  • 您也可以使用 FilenameUtils.getBasename 从路径字符串直接转到无扩展名的文件名。
  • 最简单的当然是运行 maven :-) 否则请参阅:commons.apache.org/io
  • 对于喜欢番石榴的人,it can do this too。 (这些天我个人对添加 Apache Commons 依赖项感觉不太好,尽管从历史上看,这些库一直非常有用。)
  • 虽然 Guava 和 Commons-IO 可能会提供一些额外的功能,但您会惊讶于java.nio.file.FilesPath 中已经包含在 JDK 7 中的许多便利方法-- 如解析基目录、单行复制/移动文件、只获取文件名等
  • @Lan Durkan 当前 FilenameUtils.getBaseName 大写 N
【解决方案2】:

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

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

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

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

【讨论】:

  • Regex 不像上面的库解决方案那样好用。它可以工作,但查看代码(无需解释 REGEX)并不清楚它的作用。
  • @GustavoLitovsky Android 没有与org.apache.commons 捆绑在一起。据我所知,这是在 Android 中执行此操作的唯一方法。
  • /* 以下正则表达式也会删除路径 */ "/the/path/name.extension".replaceAll(".*[\\\\/]|\\.[^\\. ]*$","");
  • 我会在第二个字符类中添加斜杠,以确保您不会被“/foo/bar.x/baz”之类的路径绊倒
  • 不必担心路径创建File对象然后getName就可以了,然后使用这个正则表达式。
【解决方案3】:

这是我喜欢的综合列表顺序。

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

Files.getNameWithoutExtension

或使用 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);
}
if (fileName.indexOf(".") > 0) {
   return fileName.substring(0, fileName.lastIndexOf("."));
} else {
   return fileName;
}
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());

【讨论】:

    【解决方案4】:

    查看以下测试程序:

    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, foo.tar.gzfoo.tar 的压缩版本,因此您也可以争辩说gz 是扩展名。这一切都归结为如何您定义扩展。
    • 如何处理像.gitignore这样的文件?
    • 你知道java中的类名不应该以小写字母开头!
    • 如果这是一个规则,语言会强制执行它。既然它没有,它是一个指导方针,无论它被强烈建议。无论如何,这与问答完全无关。
    【解决方案5】:

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

    (本质上与来自 Apache Commons IO 的 FilenameUtils.removeExtension() 相同,正如 highest-voted answer 所建议的那样。只是想指出 Guava 也这样做。就我个人而言,我不想向 Commons 添加依赖项——我觉得这是一个有点遗物——正因为如此。)

    【讨论】:

    • 其实更像FilenameUtils.getBaseName()
    • 实际上番石榴是一个非常不稳定的库,我只是尽可能避免使用它。比起 googel 的实验,更喜欢稳定的遗物
    【解决方案6】:

    以下是来自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);
        }
    }
    

    【讨论】:

    • 不错的信息,但用户要注意像“.htaccess”这样的情况,此方法将返回“”。
    【解决方案7】:

    如果您不喜欢导入完整的 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;
            }
        }
    }
    

    【讨论】:

      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

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

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

        所以split[0] 将返回“test”,而 split[1] 将返回“txt”

        【讨论】:

        • 如果文件包含多个'.'怎么办?在这种情况下,这种方法会产生意想不到的结果。
        【解决方案10】:
        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("."));
            }
        

        【讨论】:

          【解决方案11】:

          流畅的方式:

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

          【讨论】:

          • 你会用“directory.old/filenoext”做什么?
          【解决方案12】:

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

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

          【讨论】:

            【解决方案13】:

            对于 Kotlin,它现在很简单:

            val fileNameStr = file.nameWithoutExtension
            

            【讨论】:

              【解决方案14】:
              fileEntry.getName().substring(0, fileEntry.getName().lastIndexOf("."));
              

              【讨论】:

                【解决方案15】:

                给定字符串filename,您可以这样做:

                String filename = "test.xml";
                filename.substring(0, filename.lastIndexOf("."));   // Output: test
                filename.split("\\.")[0];   // Output: test
                

                【讨论】:

                  【解决方案16】:

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

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

                  【讨论】:

                    【解决方案17】:

                    使用来自 Apache Commons IO

                    FilenameUtils.removeExtension

                    例子:

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

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

                    希望这会有所帮助..

                    【讨论】:

                    • 这已经在接受的答案中了,这篇文章的意义何在?
                    【解决方案18】:

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

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

                    这在 fileNameWithExt 包含完全限定路径时也有效。

                    【讨论】:

                      【解决方案19】:

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

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

                      【讨论】:

                        【解决方案20】:

                        com.google.common.io.Files

                        Files.getNameWithoutExtension(sourceFile.getName())

                        也可以做事

                        【讨论】:

                          【解决方案21】:

                          试试下面的代码。使用核心 Java 基本功能。它处理带有扩展名的Strings,没有扩展名(没有'.' 字符)。多个'.'的情况也涵盖了。

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

                          【讨论】:

                          • 自己实现这种功能是非常糟糕的做法。乍一看,这个任务似乎非常明显,但实际上你会遇到很多异常的情况(比如文件名中没有.,或者文件是一个备份,名称如document.docx.backup 等)。使用为您处理所有这些特殊情况的外部库要可靠得多。
                          • 另一方面,将许多库添加到您的项目中会使其更大。像这样简单的事情,你自己就可以完成。
                          • 你自己不应该这样做。这很难:没有扩展名但 .在路径、ftp 路径、windows 和 unix 斜杠、符号链接等...你肯定会失败,并且通过尝试获得一些内存,你会增加很多不稳定性。如果许可证允许,至少要复制已建立代码的来源。
                          • 这段代码看起来像来自 Amit Mishra 的代码,除了那令人生畏的 'if (!str.contains("."))'
                          • 在以下情况下会失败“/someFolder/some.other.folder/someFileWithoutExtention”。 2 秒后想到的第一件事.. 我敢肯定我可以想出大量其他示例。
                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-06-30
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-01-13
                          • 1970-01-01
                          相关资源
                          最近更新 更多