获取没有扩展名的文件名

341

在获取特定文件夹中的文件名时:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
foreach (FileInfo fi in smFiles)
{
    builder.Append(fi.Name);
    builder.Append(", ");
    ...
}

fi.Name 给我文件名带有扩展名:file1.txtfile2.txtfile3.txt

如何获取没有扩展名的文件名?(file1file2file3

14个回答

588
你可以使用 Path.GetFileNameWithoutExtension 方法:
foreach (FileInfo fi in smFiles)
{
    builder.Append(Path.GetFileNameWithoutExtension(fi.Name));
    builder.Append(", ");
}

虽然我很惊讶没有直接从FileInfo获取这个的方式(或者至少我没看到)。


10
要获取文件扩展名(例如稍后添加),请使用:Path.GetExtension(fileName); - Justin
4
如果你已经有了一个FileInfo对象,那么使用Path可能就没必要了。FileInfo已经提供了"Extension"属性来完成相同的功能。如果你在处理裸字符串,那么使用Path很方便。 - jmbpiano
我得到了错误提示,“'builder' 在当前上下文中不存在”。我添加了'system.Text',但仍然出现了相同的错误。原因是什么? - ffttyy
@ffttyy 在 OP 的代码中,builder 将是 StringBuilder 的一个实例。这只是使用 GetFileNameWithoutExtension 的一个示例 - 你可能会更好地编写自己的调用它的代码。 - Rup
10
需要注意的一点是,如果您的文件名包含双重扩展名,在使用GetFileNameWithoutExtension函数时,它只会删除末尾的扩展名。例如,文件名为 example.es6.js 将变成 example.es6 - David Roberts

54

请注意,Path.GetFileNameWithoutExtension 不是最佳方法,因为它检查无效路径字符并尝试在循环中提取 DirectorySeparatorChar、AltDirectorySeparatorChar 或 VolumeSeparatorChar,这似乎对文件名(而不是完整路径)不必要! - S.Serpooshan

24

这个解决方案还可以防止添加尾随逗号。

var filenames = String.Join(
                    ", ",
                    Directory.GetFiles(@"c:\", "*.txt")
                       .Select(filename => 
                           Path.GetFileNameWithoutExtension(filename)));

对于这种情况,我不喜欢使用DirectoryInfo和FileInfo。

DirectoryInfo和FileInfo收集的关于文件夹和文件的数据比实际需要的更多,因此会花费更多的时间和内存。


2
我也更喜欢使用Directory.GetFiles而不是DirectoryInfo.GetFiles,如果我只需要文件名的话。 - Yogesh
我喜欢这个,因为它使用了String.Join、LINQ,没有StringBuilder。 - Csaba Toth
如果你看一下源代码,FileInfo的构造函数非常轻量级。所有你看到的信息都是通过属性完成的。它们只在你调用它们时被收集。 - fjch1997
@fjch1997 - 构造函数确实调用了Path.GetFileName并检查了权限。所以这似乎有点多余。 - Emond
@ErnodeWeerd FileIOPermission 不会根据 ACL 检查权限。相反,它是 .NET 中一种检查部分受信任代码权限的机制。因此,它不应该进行任何实际的 IO 调用。它对性能的影响有多大?我无法在没有测试的情况下说出来。但我认为它并不会有太大的影响。 - fjch1997
另外,为了简化操作,您不需要使用lambda表达式。只需执行以下操作:Directory.GetFiles(@"C:\", "*.txt").Select(Path.GetFileNameWithoutExtension) - iheartcsharp

21

谢谢,最好的答案总是最简短的答案。 - Ashraf Sada
但在这种情况下,它只是被接受的答案的复制,5年后... - Grim
这是不正确的。'Path.GetFileName(FileName);'“返回由只读字符跨度表示的文件路径的文件名和扩展名。”我使用了上面提到的源。https://msdn.microsoft.com/en-us/library/system.io.path(v=vs.110).aspx - Lynn

12

使用 Path.GetFileNameWithoutExtension 方法。Path 在 System.IO 命名空间中。


9

FileInfo知道它自己的扩展名,所以你可以直接删除它。

fileInfo.Name.Replace(fileInfo.Extension, "");
fileInfo.FullName.Replace(fileInfo.Extension, "");

如果您担心它可能出现在中间,或者想要进行微调优:

file.Name.Substring(0, file.Name.Length - file.Extension.Length)

7
作为额外的答案(或在现有答案的基础上),你可以编写一个扩展方法,在DirectoryInfo类中完成此任务。以下是我快速编写的样本,可以完善以提供目录名称或其他修改条件等:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace DocumentDistributor.Library
{
    public static class myExtensions
    {
        public static string[] GetFileNamesWithoutFileExtensions(this DirectoryInfo di)
        {
            FileInfo[] fi = di.GetFiles();
            List<string> returnValue = new List<string>();

            for (int i = 0; i < fi.Length; i++)
            {
                returnValue.Add(Path.GetFileNameWithoutExtension(fi[i].FullName)); 
            }

            return returnValue.ToArray<string>();
         }
    }
}

编辑: 我认为这种方法可能可以通过使用LINQ来简化或使其更加优秀,但我没有足够的LINQ经验来快速地为这样一个示例构建数组。

编辑2(差不多四年后): 这是我将使用的经过LINQ处理的方法:

public static class myExtensions
{
    public static IEnumerable<string> GetFileNamesWithoutExtensions(this DirectoryInfo di)
    {
        return di.GetFiles()
            .Select(x => Path.GetFileNameWithoutExtension(x.FullName));
    }
}

5
如果文件名包含目录并且您不想丢失目录:
fileName.Remove(fileName.LastIndexOf("."))

3

试一下这个:

string FileNameAndExtension =  "bılah bılah.pdf";
string FileName = FileNameAndExtension.Split('.')[0];

注意!不适用于文件名中有额外点的情况... - SiL3NC3
是的,在这种情况下,需要仅按最后一个句点进行拆分。 - Ali CAKIL

1

如果你已经有一个FileInfo对象,使用Path.GetFileNameWithoutExtension似乎会很混乱。

因此,您可以利用FileInfo.ExtensionFileInfo.Name的一部分这一事实来进行简单的字符串操作,只需删除字符串的结尾即可:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
foreach (FileInfo fi in smFiles)
{
    var name = fileInfo.Name.Remove(fileInfo.Name.Length - fileInfo.Extension.Length);
    builder.Append(name);
    builder.Append(", ");
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接