URLEncode会用文件名(C#)中的非法字符修复此问题吗?

时间:2009-07-03 05:59:58

标签: c# urlencode illegal-characters

我正在构建一个应用程序,它使用精心设计的API从Youtube获取数据,数据文件以相应视频的名称作为文件名保存。但是,我的程序崩溃了,因为YouTube上的很多视频都有其标题中的字符,这些字符在Windows下的文件名中是非法的。

URLEncoding视频标题会解决这个问题吗?

如果是这样,这是最好的使用方法,实现URLEncode的最佳方法是什么?

谢谢! :)

4 个答案:

答案 0 :(得分:4)

如果您想要进行网址编码,可以使用HttpUtility.UrlEncode。我不确定我会不会。 可以删除你想要它的所有字符,但它也会做其他人。

我想我可能会使用Path.GetInvalidFilenameChars,只需用下划线替换名称中无效的内容。

当然,这不是一种可逆的编码,但我认为它会产生更容易理解的文件名。您可能想要创建一个索引文件,该文件也会从原始标题映射到文件名。

答案 1 :(得分:1)

Url Encoding应该解决问题,因为它应该用'%'后跟一组十六进制替换任何无效的char(和一些有效的char);据我所知,这对文件系统名称有效。

这引出了两个问题:

  1. 能够干净地读取对用户重要的文件名吗?如果没有,最好使用唯一的文件名(1.file,2.file,3.file)和文件名的映射 - >标题

  2. 如果两个视频的名称相同,会怎样?我想是第一个问题的扩展类型。

  3. 如果标题(当编码网址时)长于最大文件名长度怎么办?如果我没记错的话,NTFS上文件名的最大长度为255个字符;如果标题中的每个字符扩展为3个字符以进行网址编码,则可以使用85个字符标题来满足255个字符限制。

  4. 编辑/更新:UrlEncode认为有些字符无效,这些字符是无效的文件系统字符;我特意遇到的是'\'。所以,不,Url编码不安全。

答案 2 :(得分:0)

您可以使用youtube的视频ID代替视频名称吗?例如V = Yk6oPsKZG_w。或者你没有访问权限?这些似乎包含简单的字母数字,在youtube中应该是唯一的。

我不确定urlencode是否会帮助您使用视频名称中的星号。

如果您仍想使用视频名称,可能需要使用“\\?\”前缀,该前缀告诉Win32 API禁用所有字符串解析并将此字符串直接发送到文件系统。

http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#path_names_and_namespaces

我不确定,如果您可以在.NET API中使用它,或者您必须使用DllImport直接调用Win32 API。

答案 3 :(得分:0)

我最后还是遇到了类似的问题:

    static string Escape(string input)
    {
        StringBuilder builder = new StringBuilder(input.Length);
        for (int i = 0; i < input.Length; i++)
        {
            if (Path.GetInvalidPathChars().Contains(input[i]) || Path.GetInvalidFileNameChars().Contains(input[i]) || input[i] == '%')
            {
                builder.Append(Uri.HexEscape(input[i]));
            }
            else
            {
                builder.Append(input[i]);
            }
        }
        return builder.ToString();
    }

    static string Unescape(string input)
    {
        StringBuilder builder = new StringBuilder(input.Length);
        int index = 0;
        while (index < input.Length)
        {
            builder.Append(Uri.HexUnescape(input, ref index));
        }
        return builder.ToString();
    }

编写所有这些代码感觉有点奇怪,但至少我得到了可以安全使用操作系统的可读文件名。