如何匹配指向同一文件的两条路径?

时间:2012-07-13 06:24:10

标签: c# path filesystems

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

格式示例:

  

List1:file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3   
列表2:\\ FILE \ Musik \ 30秒到Mars.mp3

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

4 个答案:

答案 0 :(得分:1)

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

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

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

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

尽管如此,“算法”将是这样的:

  • 找出您拥有的URL,UNC路径/共享等的源路径
  • 计算出这些路径的本地源路径(考虑链接/联结,subst.exe等)。
  • 如有必要,请对这些路径进行规范化(即a/b/../c实际为a/c
  • 比较生成的路径。

答案 1 :(得分:0)

我认为最好的方法是暂时将其中一条路径转换为另一条路径。我建议你改变第一个以匹配第二个。

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

我建议你使用Replace() - 方法。

  1. 摆脱“file:// localhost”:

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

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

    tempStr = List1.Replace("/", "\");
    
  4. 瞧!要匹配格式的字符串!

答案 2 :(得分: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')

答案 3 :(得分: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();

        }
    }
}