C#中调用Path.GetFileNameWithoutExtension解析编号失败

问题描述

  帮单位同事编写从其它系统接收零件信息的模块,其中一个属性是零件编号,零件编号是有编号规则的,但是测试过程中发现有些编号填写不规范,编号会以文件名的形式传过来,形式如XXX-XX-XXXX.dwg等。于是在接收零件信息,保存零件编号时,对零件编号做了处理,如果带后缀名,则去掉后缀名,只保留前面的名称。
  在实际使用过程中,用户偶尔会反馈,接收过来的零件编号不对,只有一部分内容,还需要用户手动补全编号内容。具体的问题如零件编号为XXX-XX-XXXX/F2,则接收后只显示为F2。

原因分析

  通过查看代码,发现接收零件信息并保存零件编号时对其进行了处理,如果包含文件后缀名,则去掉文件后缀名,只保留前面的内容。当时为了省事儿,直接调用的System.IO命名空间中的Path.GetFileNameWithoutExtension解析编号,就是调用这个函数出的问题。
  MSDN中给的示例如下,通过示例及示例的输出可以看到,GetFileNameWithoutExtension函数返回不带文件后缀名的文件名称,如果文件名带路径,也会把路径去掉。

string fileName = @"C:\mydir\myfile.ext";
string path = @"C:\mydir\";
string result;

result = Path.GetFileNameWithoutExtension(fileName);
Console.WriteLine("GetFileNameWithoutExtension('{0}') returns '{1}'", 
    fileName, result);

result = Path.GetFileName(path);
Console.WriteLine("GetFileName('{0}') returns '{1}'", 
    path, result);

// This code produces output similar to the following:
//
// GetFileNameWithoutExtension('C:\mydir\myfile.ext') returns 'myfile'
// GetFileName('C:\mydir\') returns ''

  此时,问题的原因已经比较清晰,当时做功能测试时仅是测了比较简单的编号形式XXX-XX-XXXX,没有测试XXX-XX-XXXX/F2形式的编号,GetFileNameWithoutExtension解析XXX-XX-XXXX/F2时,估计是把它当成相对路径来解析了,为了验证想法,找到GetFileNameWithoutExtension的源码看看,代码如下:

        // Returns the name and extension parts of the given path. The resulting
        // string contains the characters of path that follow the last
        // backslash ("\"), slash ("/"), or colon (":") character in 
        // path. The resulting string is the entire path if path 
        // contains no backslash after removing trailing slashes, slash, or colon characters. The resulting 
        // string is null if path is null.
        //
        [Pure]
        public static String GetFileName(String path) {
          if (path != null) {
                CheckInvalidPathChars(path);
    
                int length = path.Length;
                for (int i = length; --i >= 0;) {
                    char ch = path[i];
                    if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar)
                        return path.Substring(i + 1, length - i - 1);

                }
            }
            return path;
        }

        [Pure]
        public static String GetFileNameWithoutExtension(String path) {
            path = GetFileName(path);
            if (path != null)
            {
                int i;
                if ((i=path.LastIndexOf('.')) == -1)
                    return path; // No path extension found
                else
                    return path.Substring(0,i);
            }
            return null;
         }

  通过上述代码逻辑可以看到,GetFileNameWithoutExtension函数传入文件名后,首先调用GetFileName函数获取文件名称,GetFileName的函数逻辑是从后往前找‘\’、’/’、’:‘字符,找到就去该字符后面的内容作为文件名称返回。我之前程序中的问题就是因此产生的,把’/'之前的部分编号当成路径给去掉了。

解决方案

  问题找到了,解决方法就比较简单,直接把GetFileNameWithoutExtension中的部分代码复制过来,只检查编号中是否有’.’,有的话就取前面的内容,代码如下:

            if (partNo != null)
            {
                int i;
                if ((i=partNo .LastIndexOf('.')) == -1)
                    return partNo ; // No path extension found
                else
                    return partNo .Substring(0,i);
            } 

  问题解决的比较简容易,但是之前写代码时没有测试完整才是最大的问题,以后还是不能犯懒才行。

参考文献:
[1]https://docs.microsoft.com/zh-cn/dotnet/api/system.io.path.getfilenamewithoutextension?redirectedfrom=MSDN&view=netframework-4.8
[2]https://referencesource.microsoft.com/,可以在这里免费下.net framework的源码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值