2

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

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

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

谢谢!:)

4

4 回答 4

4

那么如果你想做 url 编码,你可以使用HttpUtility.UrlEncode. 我不确定我会。它可能会删除您想要的所有字符,但它也会删除其他字符。

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

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

于 2009-07-03T06:08:36.860 回答
1

网址编码应该可以解决问题,因为它应该用 '%' 后跟一组十六进制替换任何无效字符(和一些有效字符);据我所知,这对文件系统名称有效。

但这引出了两个问题:

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

  2. 如果两个视频名称相同会​​怎样?我认为这是第一个问题的延伸。

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

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

于 2009-07-03T06:08:48.013 回答
1

我最终遇到了类似的问题:

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

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

于 2010-10-21T11:48:26.243 回答
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。

于 2009-07-03T06:22:01.593 回答