1

我有两个包含音乐文件目录路径的列表,我想确定哪些文件存储在两个列表中,哪些只存储在一个列表中。问题在于两个列表之间的路径格式不同。

格式示例:

List1:文件://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3
List2:\\FILE\Musik\30 Seconds To Mars.mp3

我该如何比较这两个文件路径并将它们匹配到相同的源?

4

4 回答 4

1

答案取决于您对“同一文件”的概念。如果您只想检查文件是否相等,但不是同一个文件,您可以简单地生成文件内容的哈希并进行比较。如果哈希值相等(请使用强哈希值,例如 SHA-256),您可以确信文件也是。同样,您当然也可以逐字节比较文件。

如果您真的想确定这两个文件实际上是同一个文件,即只是通过不同的方式(如文件 URL 或 UNC 路径)寻址,那么您还有一些工作要做。

首先,您需要找出每个地址的真实文件系统路径。例如,您需要找到 UNC 路径和/或文件 URL(通常是 URL 本身)后面的文件系统路径。对于 UNC 路径,即远程计算机上的共享,您甚至可以这样做。

此外,即使您以某种方式找到了本地路径,您也需要处理本地路径的不同重定向机制(在 Windows 联结点/重解析点/链接上;在 UNIX 符号或硬链接上)。例如,您可以使用文件系统链接作为源进行共享,而文件 URL 使用真实的源路径。所以对于不经意的观察者来说,它们仍然看起来像不同的文件。

说了这么多,“算法”应该是这样的:

  • 找出您拥有的 URL、UNC 路径/共享等的源路径
  • 从这些路径中找出本地源路径(考虑链接/连接点subst.exe等)
  • 如有必要,规范化这些路径(即a/b/../c实际上是a/c
  • 比较生成的路径。
于 2012-07-13T06:57:53.157 回答
0

我完全同意克里斯蒂安的观点,你应该重新考虑列表的结构,但下面的内容应该能让你继续前进。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication5
{
    class Program
    {
        public static List<string> SanitiseList(List<string> list)
        {

            List<string> sanitisedList = new List<string>();

            foreach (string filename in list)
            {
                String sanitisedFilename = String.Empty;

                if (!String.IsNullOrEmpty(filename))
                {
                    sanitisedFilename = filename;

                    // get rid of the encoding
                    sanitisedFilename = Uri.UnescapeDataString(sanitisedFilename);

                    // first of all change all back-slahses to forward slashes
                    sanitisedFilename = sanitisedFilename.Replace(@"\", @"/");

                    // if we have two back-slashes at the beginning assume its localhsot
                    if (sanitisedFilename.Substring(0, 2) == "//")
                    {
                        // remove these first double slashes and stick in localhost

                        sanitisedFilename = sanitisedFilename.TrimStart('/');
                        sanitisedFilename = sanitisedFilename = "//localhost" + "/" + sanitisedFilename;
                    }

                    // remove file
                    sanitisedFilename = sanitisedFilename.Replace(@"file://", "//");

                    // remove double back-slashes
                    sanitisedFilename = sanitisedFilename.Replace("\\", @"\");

                    // remove double forward-slashes (but not the first two)
                    sanitisedFilename = sanitisedFilename.Substring(0,2) + sanitisedFilename.Substring(2, sanitisedFilename.Length - 2).Replace("//", @"/");

                }

                if (!String.IsNullOrEmpty(sanitisedFilename))
                {
                    sanitisedList.Add(sanitisedFilename);
                }
            }

            return sanitisedList;
        }

        static void Main(string[] args)
        {

            List<string> listA = new List<string>();
            List<string> listB = new List<string>();

            listA.Add("file://localhost//FILE/Musik/BritneySpears.mp3");
            listA.Add("file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3");
            listB.Add("file://localhost//FILE/Musik/120%20Seconds%20To%20Mars.mp3");

            listB.Add(@"\\FILE\Musik\30 Seconds To Mars.mp3");
            listB.Add(@"\\FILE\Musik\5 Seconds To Mars.mp3");

            listA = SanitiseList(listA);
            listB = SanitiseList(listB);

            List<string> missingFromA = listB.Except(listA).ToList();
            List<string> missingFromB = listA.Except(listB).ToList();

        }
    }
}
于 2012-07-13T07:17:39.387 回答
0

使用python:您可以像这样轻松比较两个文件

    >>> import filecmp
    >>> filecmp.cmp('file1.txt', 'file1.txt')
    True
    >>> filecmp.cmp('file1.txt', 'file2.txt')
    False

要使用 file:// 语法打开文件,请使用 URLLIB

    >>> import urllib
    >>> file1 = urllib.urlopen('file://localhost/tmp/test')

对于普通文件路径,使用打开的标准文件。

    >>> file2 = open('/pathtofile','r')
于 2012-07-13T06:57:14.623 回答
0

我认为最好的方法是将其中一个路径临时转换为另一个格式。我建议您更改第一个以匹配第二个。

string List1 = "file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3" 
string List2 = "\\FILE\Musik\30 Seconds To Mars.mp3"

我建议您使用 Replace() 方法。

  1. 摆脱“文件:// localhost”:

    var tempStr = List1.Replace("file://localhost", "");
    
  2. 将所有 '%20' 更改为空格:

    tempStr = List1.Replace("%20", " ");
    
  3. 将所有 '/' 更改为 '\':

    tempStr = List1.Replace("/", "\");
    

瞧!到匹配格式的字符串!

于 2012-07-13T06:40:14.537 回答