কোনও ফাইল ইউআরআইতে ফাইলের পথ রূপান্তর করবেন?


201

.NET ফ্রেমওয়ার্কের কোনও পাথ (উদাহরণস্বরূপ "C:\whatever.txt") কে ফাইল ইউআরআইতে রূপান্তর করার জন্য কোনও পদ্ধতি আছে (যেমন "file:///C:/whatever.txt")?

System.Uri বর্গ বিপরীত (ক ফাইল কোনো URI পথটি থেকে) আছে, কিন্তু কিছুই যতদূর আমি একটি ফাইল URL এ রূপান্তরের জন্য জানতে পারেন হিসাবে।

এছাড়াও, এই হল না একটি ASP.NET আবেদন।

উত্তর:


291

System.Uriকন্সট্রাকটর পূর্ণ ফাইল পাথ বিশ্লেষণ এবং তাদের কোনো URI শৈলী পাথ পরিণত করতে সক্ষম। সুতরাং আপনি কেবল নিম্নলিখিতটি করতে পারেন:

var uri = new System.Uri("c:\\foo");
var converted = uri.AbsoluteUri;

78
var path = new Uri("file:///C:/whatever.txt").LocalPath;যার প্রয়োজন হয় তার জন্যও একটি ইউরি স্থানীয় ফাইলপথে পরিণত করে।
পন্ডিদাম

2
একটি নোট হিসাবে। এই জাতীয় উরি সেশন উইন্ডোতে ভিএস আউটপুট এবং আর # ইউনিট পরীক্ষার আউটপুটে
ক্লিকযোগ্য

7
দুর্ভাগ্যক্রমে এটি সঠিক নয়। উদাহরণস্বরূপ new Uri(@"C:\%51.txt").AbsoluteUriআপনাকে "file:///C:/Q.txt"পরিবর্তে দেয়"file:///C:/%2551.txt"
poizan42

2
এটি স্পেসগুলির সাথে পাথ নিয়ে কাজ করবে না, যেমন: "সি: folder টেস্ট ফোল্ডার \ যাইহোক।
টেক্সট

অথবা এটি এমন একটি পাথের সাথে কাজ করবে যা # টি অক্ষর ধারণ করে।
লুইস

42

যে বিষয়টি কেউ অনুধাবন করতে পারে বলে মনে হয় তা হল যে কোনও System.Uriনির্মাণকারীরই নির্দিষ্ট লক্ষকে সঠিকভাবে পরিচালনা করে নি।

new Uri(@"C:\%51.txt").AbsoluteUri;

এটি আপনাকে "file:///C:/Q.txt"পরিবর্তে দেয় "file:///C:/%2551.txt"

অবহেলিত ডন্টস্ক্রপ আর্গুমেন্টের কোনও মানই কোনও পার্থক্য করে না এবং ইউরিকাইন্ড নির্দিষ্ট করে একই ফলাফল দেয়। ইউরিবিল্ডারের সাথে চেষ্টা করা কোনওভাবেই সহায়তা করে না:

new UriBuilder() { Scheme = Uri.UriSchemeFile, Host = "", Path = @"C:\%51.txt" }.Uri.AbsoluteUri

এটিও ফিরে আসে "file:///C:/Q.txt"

যতদূর আমি বলতে পারি ফ্রেমওয়ার্কটিতে আসলে এটি সঠিকভাবে করার কোনও উপায়ের অভাব রয়েছে।

আমরা ব্যাকস্ল্যাশগুলি ফরোয়ার্ড স্ল্যাশগুলির সাথে প্রতিস্থাপন করে এটির পথটি ফিড করতে পারি Uri.EscapeUriString- অর্থাৎ

new Uri(Uri.EscapeUriString(filePath.Replace(Path.DirectorySeparatorChar, '/'))).AbsoluteUri

এটি প্রথমে কাজ করছে বলে মনে হয়, তবে আপনি যদি এই পথটি দেন C:\a b.txtতবে আপনি file:///C:/a%2520b.txtতার পরিবর্তে শেষ করবেন file:///C:/a%20b.txt- কোনওভাবে এটি সিদ্ধান্ত নিয়েছে যে কিছু সিকোয়েন্সগুলি ডিকোড করা উচিত তবে অন্যকে নয়। এখন আমরা কেবল "file:///"নিজের সাথে উপসর্গ করতে পারি, তবে এটি ইউএনসি পাথগুলি বিবেচনার মতো গ্রহণ করতে ব্যর্থ হয় \\remote\share\foo.txt- যা উইন্ডোজে সাধারণত গ্রহণযোগ্য বলে মনে হয় তা হ'ল ফর্মের সিউডো-ইউআরএলগুলিতে পরিণত করা file://remote/share/foo.txt, সুতরাং আমাদের এটিও বিবেচনায় নেওয়া উচিত।

EscapeUriStringএটিরও সমস্যা আছে যে এটি '#'চরিত্রটি এড়ায় না । এটি এই মুহুর্তে মনে হবে যে স্ক্র্যাচ থেকে আমাদের নিজস্ব পদ্ধতি তৈরি করা ছাড়া আমাদের আর কোনও উপায় নেই। সুতরাং এই আমি পরামর্শ:

public static string FilePathToFileUrl(string filePath)
{
  StringBuilder uri = new StringBuilder();
  foreach (char v in filePath)
  {
    if ((v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z') || (v >= '0' && v <= '9') ||
      v == '+' || v == '/' || v == ':' || v == '.' || v == '-' || v == '_' || v == '~' ||
      v > '\xFF')
    {
      uri.Append(v);
    }
    else if (v == Path.DirectorySeparatorChar || v == Path.AltDirectorySeparatorChar)
    {
      uri.Append('/');
    }
    else
    {
      uri.Append(String.Format("%{0:X2}", (int)v));
    }
  }
  if (uri.Length >= 2 && uri[0] == '/' && uri[1] == '/') // UNC path
    uri.Insert(0, "file:");
  else
    uri.Insert(0, "file:///");
  return uri.ToString();
}

এটি ইচ্ছাকৃতভাবে + এবং: আনইনকোড ছাড়ায় যা মনে হয় এটি উইন্ডোজে সাধারণত কীভাবে হয়। এটি শুধুমাত্র লাতিন 1 কে এনকোড করে কারণ ইন্টারনেট এক্সপ্লোরার এনকোড করা থাকলে ফাইল ইউআরএলগুলিতে ইউনিকোড অক্ষর বুঝতে পারে না।


এমন কোনও নুগেট রয়েছে যাতে এটি উদার লাইসেন্স সহ অন্তর্ভুক্ত? দুঃখের বিষয় এর কাঠামোটিতে বিদ্যমান থাকার পক্ষে সঠিক কোনও উপায় নেই এবং কোপাইপাস্টা আপডেট করা খুব শক্ত ...
বিনকি

4
আপনি এমআইটি লাইসেন্সের শর্তাবলী অনুসারে উপরের কোডটি ব্যবহার করতে পারেন (আমি এমন কিছু বিশ্বাস করি না যা সংক্ষিপ্ত এমনকি কপিরাইটযোগ্য হওয়া উচিত, তবে এখন আপনার স্পষ্ট অনুদান রয়েছে)
poizan42

9

উপরের সমাধানগুলি লিনাক্সে কাজ করে না।

.NET কোর ব্যবহার করে, new Uri("/home/foo/README.md")ব্যতিক্রমের ফলাফলগুলি কার্যকর করার চেষ্টা করছে :

Unhandled Exception: System.UriFormatException: Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString)
   ...

আপনার কী ধরণের ইউআরএল রয়েছে সে সম্পর্কে আপনাকে সিএলআরকে কিছু ইঙ্গিত দেওয়া দরকার।

এইটা কাজ করে:

Uri fileUri = new Uri(new Uri("file://"), "home/foo/README.md");

... এবং স্ট্রিং দ্বারা ফিরে fileUri.ToString()হয়"file:///home/foo/README.md"

এটি উইন্ডোজেও কাজ করে।

new Uri(new Uri("file://"), @"C:\Users\foo\README.md").ToString()

... নিঃসরণ করে "file:///C:/Users/foo/README.md"


আপনি যদি জানেন যে পথটি আপনি নিখুঁত হয় তবে আপনি ব্যবহার করতে পারেনnew Uri("/path/to/file", UriKind.Absolute);
মিনিজ্যাক

8

VB.NET:

Dim URI As New Uri("D:\Development\~AppFolder\Att\1.gif")

বিভিন্ন আউটপুট:

URI.AbsolutePath   ->  D:/Development/~AppFolder/Att/1.gif  
URI.AbsoluteUri    ->  file:///D:/Development/~AppFolder/Att/1.gif  
URI.OriginalString ->  D:\Development\~AppFolder\Att\1.gif  
URI.ToString       ->  file:///D:/Development/~AppFolder/Att/1.gif  
URI.LocalPath      ->  D:\Development\~AppFolder\Att\1.gif

এক রৈখিক:

New Uri("D:\Development\~AppFolder\Att\1.gif").AbsoluteUri

আউটপুট :file:///D:/Development/~AppFolder/Att/1.gif


2
AbsoluteUriএটি একটি সঠিক কারণ এটি% 20 এও ফাঁকা জায়গা এনকোড করে।
psulek

আমি নিশ্চিত যে এই উত্তরে বর্ণিত একই সমস্যাগুলির মধ্যে ভুগছে যা বিশেষ চরিত্র পরিচালনা সম্পর্কে আলোচনা করে
বিনকি


2

আরলক্রিয়াটফ্র্যামপথ থেকে উদ্ধার! ঠিক আছে, পুরোপুরি নয়, কারণ এটি প্রসারিত এবং ইউএনসি পথ ফর্ম্যাটগুলিকে সমর্থন করে না, তবে এটি অতিক্রম করা এত কঠিন নয়:

public static Uri FileUrlFromPath(string path)
{
    const string prefix = @"\\";
    const string extended = @"\\?\";
    const string extendedUnc = @"\\?\UNC\";
    const string device = @"\\.\";
    const StringComparison comp = StringComparison.Ordinal;

    if(path.StartsWith(extendedUnc, comp))
    {
        path = prefix+path.Substring(extendedUnc.Length);
    }else if(path.StartsWith(extended, comp))
    {
        path = prefix+path.Substring(extended.Length);
    }else if(path.StartsWith(device, comp))
    {
        path = prefix+path.Substring(device.Length);
    }

    int len = 1;
    var buffer = new StringBuilder(len);
    int result = UrlCreateFromPath(path, buffer, ref len, 0);
    if(len == 1) Marshal.ThrowExceptionForHR(result);

    buffer.EnsureCapacity(len);
    result = UrlCreateFromPath(path, buffer, ref len, 0);
    if(result == 1) throw new ArgumentException("Argument is not a valid path.", "path");
    Marshal.ThrowExceptionForHR(result);
    return new Uri(buffer.ToString());
}

[DllImport("shlwapi.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int UrlCreateFromPath(string path, StringBuilder url, ref int urlLength, int reserved);

যদি কোনও বিশেষ উপসর্গ দিয়ে পথটি শুরু হয় তবে এটি সরিয়ে ফেলা হবে। যদিও ডকুমেন্টেশনটিতে এটি উল্লেখ করা হয়নি, বাফারটি ছোট হলেও ফাংশনটি ইউআরএলের দৈর্ঘ্যকে আউটপুট করে দেয়, তাই আমি প্রথমে দৈর্ঘ্যটি পাই এবং তারপরে বাফারটি বরাদ্দ করি।

কিছু খুব , নির্দিষ্টভাবে "\\ স্থানীয় হোস্ট \ পথ" শুধু "ফাইল: /// পথ" থেকে রুপান্তরিত হয়: আকর্ষণীয় পর্যবেক্ষণ আমার কাছে তা থাকত যেখানে "\\ ডিভাইস \ পথ" সঠিকভাবে "// ডিভাইস / পাথ ফাইল" রুপান্তরিত হয় ।

WinApi ফাংশন সঙ্কেতাক্ষরে লিখা বিশেষ অক্ষর পরিচালিত, কিন্তু পাতার ইউনিকোড-নির্দিষ্ট অক্ষর মতো unencoded উরি construtor। সেক্ষেত্রে, AbsoluteUri যখন, সঠিকভাবে এনকোড URL টিকে নিজের OriginalString ইউনিকোড অক্ষর ধরে রাখা ব্যবহার করা যাবে।


0

কর্মক্ষেত্রটি সহজ। কেবলমাত্র ইউরি ()। টুস্ট্রিং () পদ্ধতি এবং শতাংশ-এনকোড সাদা-স্পেসগুলি যদি থাকে তবে পরে ব্যবহার করুন।

string path = new Uri("C:\my exampleㄓ.txt").ToString().Replace(" ", "%20");

সঠিকভাবে ফাইলটি ফেরত দেয় : /// সি: / আমার% 20 উদাহরণ ㄓ। txt xt

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.