1

音楽ファイルのディレクトリへのパスを含む 2 つのリストがあり、これらのファイルのどちらが両方のリストに保存され、どれが 1 つだけに保存​​されているかを判断したいと考えています。問題は、パスの形式が 2 つのリスト間で異なることにあります。

フォーマットの例:

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

これら 2 つのファイル パスを比較して、同じソースに一致させるにはどうすればよいですか?

4

4 に答える 4

1

答えは、「同じファイル」の概念によって異なります。ファイルが等しいかどうかを確認したいだけで、まったく同じファイルではない場合は、ファイルのコンテンツに対してハッシュを生成し、それを比較するだけです。ハッシュが等しい場合 (SHA-256 などの強力なハッシュを使用してください)、ファイルも同じであると確信できます。同様に、もちろんファイルをバイトごとに比較することもできます。

2 つのファイルが実際には同じファイルである、つまり別の方法 (ファイル 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を使用する:このように2つのファイルを簡単に比較できます

    >>> 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

それを行う最善の方法は、パスの1つを一時的に他のパスの形式に変換することだと思います。最初のものを2番目のものと一致するように変更することをお勧めします。

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("/", "\");
    

ほら!一致する形式の文字列に!

于 2012-07-13T06:40:14.537 に答える