从文件名字符串中去除文件扩展名

282

如果我有一个字符串,比如说"abc.txt",有没有一种快速的方式可以得到只包含"abc"的子串?

我不能使用fileName.IndexOf('.'),因为文件名可能是"abc.123.txt"之类的,而我显然只想去掉扩展名(即"abc.123")。

13个回答

482

1
本来想建议使用以下代码:string.Format( "{0}\{1}", Path.GetDirectoryName( path ), Path.GetFileNameWithoutExtension( path ) )......但是我看到下面有一个更好的版本,它使用Path.Combine而不是String.Format! - emery.noel
7
保留路径不是期望的效果,请注意方法名称是GetFileNameWithoutExtension。 如果承诺保留路径,则方法名称应该不同。方法描述也非常明确,仅返回没有扩展名的文件名。原帖中并未指定需要路径,相反地。 - Morten Bork
2
@dukevin,这个问题与路径无关,仅仅是要求从文件名中移除扩展名。 - Rory McCrossan
对于那些需要的人,完全限定的函数名是System.IO.path.GetFileNameWithoutExtension。 - gouderadrian

336

框架中有一个方法可以实现此目的,它将保留完整的路径,但不包括扩展名。

System.IO.Path.ChangeExtension(path, null);

如果只需要文件名,请使用

System.IO.Path.GetFileNameWithoutExtension(path);

53
这是正确答案。被接受的答案去掉了文件路径。 - dukevin
9
这是一个更好的答案,因为它保留了路径。 - James H
10
这里的 null 具有神奇的意义。如果你使用 String.Empty 或者 "",最后会留下一个句点 [.]。 - THBBFT
我不同意这个答案更好。GetFileNameWithoutExtension 更加明确。虽然了解它的潜在副作用和避免它的替代方法也是很好的。 - jeromej
1
在Powershell v5.1或v7.1中无法工作。系统将[System.IO.Path]::ChangeExtension($FilePath,$null)解释为[System.IO.Path]::ChangeExtension($FilePath,'')[System.IO.Path]::ChangeExtension($FilePath,[string]::Empty) - Bacon Bits

60

你可以使用

string extension = System.IO.Path.GetExtension(filename);

然后手动删除扩展名:

string result = filename.Substring(0, filename.Length - extension.Length);

@Bio,实际上这获取了扩展名的长度,然后获取了文件名直到扩展名。 - Neville
1
如果您决定忽略System.IO.Path的功能,那么获取文件扩展名的最好方式是否是:string extension = filename.Substring(filename.LastIndexOf('.'));? - QMaster

33

可以使用String.LastIndexOf方法。

string fileName= "abc.123.txt";
int fileExtPos = fileName.LastIndexOf(".");
if (fileExtPos >= 0 )
 fileName= fileName.Substring(0, fileExtPos);

10
请注意没有扩展名的文件,例如 foo/bar.cat/cheese!请警惕! - Cameron
String.LastIndexOf 对于类似这样的操作来说是有风险的。对于没有扩展名的文件,就像 @Cameron 上面所说的那样,你得到的结果可能不是你想要的。最安全的方法是使用 @Logman 上面的答案。 - Shiva
@Shiva,但是对于logman的回答,你需要访问该文件。如果你只有文件名作为字符串... - Leandro Bardelli

16

如果您想创建没有扩展名的完整路径,可以尝试以下方法:

Path.Combine( Path.GetDirectoryName(fullPath), Path.GetFileNameWithoutExtension(fullPath))

但我正在寻找更简单的方法来做到这一点。有人有什么想法吗?


15
我使用了以下更少的代码。
string fileName = "C:\file.docx";
MessageBox.Show(Path.Combine(Path.GetDirectoryName(fileName),Path.GetFileNameWithoutExtension(fileName)));

输出将为

C:\file


2
如果我的目录分隔符是“/”呢? - Logman
4
使用Path.Combine()而不是直接指定"\\" - Broots Waymb

4

您可能不会使用UWP API。但在UWP中,file.DisplayName是没有扩展名的名称。希望对其他人有用。


1
如果你想使用字符串操作,那么可以使用函数 lastIndexOf() 来搜索字符或子字符串的最后一次出现。Java 有许多字符串函数。

-1
ReadOnlySpan<char> filename = "abc.def.ghi.txt";
var fileNameWithoutExtension = RemoveFileExtension(filename); //abc.def.ghi

string RemoveFileExtension(ReadOnlySpan<char> path)
{
    var lastPeriod = path.LastIndexOf('.');
    return (lastPeriod < 0 ? path : path[..lastPeriod]).ToString();
}

-1

我知道这是一个老问题,而 Path.GetFileNameWithoutExtension 是一个更好的,也许更干净的选项。但就我个人而言,我已经将这两种方法添加到我的项目中并希望分享它们。这需要 C# 8.0,因为它使用范围和索引。

public static string RemoveExtension(this string file) => ReplaceExtension(file, null);

public static string ReplaceExtension(this string file, string extension)
{
    var split = file.Split('.');

    if (string.IsNullOrEmpty(extension))
        return string.Join(".", split[..^1]);

    split[^1] = extension;

    return string.Join(".", split);
}

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