我有两个包含音乐文件目录路径的列表,我想确定哪些文件存储在两个列表中,哪些只存储在一个列表中。问题在于两个列表之间的路径格式不同。
格式示例:
List1:文件://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3
List2:\\FILE\Musik\30 Seconds To Mars.mp3
我该如何比较这两个文件路径并将它们匹配到相同的源?
我有两个包含音乐文件目录路径的列表,我想确定哪些文件存储在两个列表中,哪些只存储在一个列表中。问题在于两个列表之间的路径格式不同。
格式示例:
List1:文件://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3
List2:\\FILE\Musik\30 Seconds To Mars.mp3
我该如何比较这两个文件路径并将它们匹配到相同的源?
答案取决于您对“同一文件”的概念。如果您只想检查文件是否相等,但不是同一个文件,您可以简单地生成文件内容的哈希并进行比较。如果哈希值相等(请使用强哈希值,例如 SHA-256),您可以确信文件也是。同样,您当然也可以逐字节比较文件。
如果您真的想确定这两个文件实际上是同一个文件,即只是通过不同的方式(如文件 URL 或 UNC 路径)寻址,那么您还有一些工作要做。
首先,您需要找出每个地址的真实文件系统路径。例如,您需要找到 UNC 路径和/或文件 URL(通常是 URL 本身)后面的文件系统路径。对于 UNC 路径,即远程计算机上的共享,您甚至可以这样做。
此外,即使您以某种方式找到了本地路径,您也需要处理本地路径的不同重定向机制(在 Windows 联结点/重解析点/链接上;在 UNIX 符号或硬链接上)。例如,您可以使用文件系统链接作为源进行共享,而文件 URL 使用真实的源路径。所以对于不经意的观察者来说,它们仍然看起来像不同的文件。
说了这么多,“算法”应该是这样的:
subst.exe
等)a/b/../c
实际上是a/c
)我完全同意克里斯蒂安的观点,你应该重新考虑列表的结构,但下面的内容应该能让你继续前进。
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();
}
}
}
使用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')
我认为最好的方法是将其中一个路径临时转换为另一个格式。我建议您更改第一个以匹配第二个。
string List1 = "file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3"
string List2 = "\\FILE\Musik\30 Seconds To Mars.mp3"
我建议您使用 Replace() 方法。
摆脱“文件:// localhost”:
var tempStr = List1.Replace("file://localhost", "");
将所有 '%20' 更改为空格:
tempStr = List1.Replace("%20", " ");
将所有 '/' 更改为 '\':
tempStr = List1.Replace("/", "\");
瞧!到匹配格式的字符串!