উইন্ডোজের অধীনে প্রদত্ত স্ট্রিং আইনী / বৈধ ফাইলের নাম কিনা তা আমি কীভাবে চেক করব?


165

আমি আমার অ্যাপ্লিকেশনে একটি ব্যাচের ফাইলের পুনরায় নামকরণ কার্যকারিতা অন্তর্ভুক্ত করতে চাই। কোনও ব্যবহারকারী একটি গন্তব্য ফাইলের নাম প্যাটার্ন টাইপ করতে পারেন এবং (প্যাটার্নে কিছু ওয়াইল্ডকার্ড প্রতিস্থাপনের পরে) এটি যা উইন্ডোজের অধীনে আইনী ফাইল নাম হতে চলেছে তা আমাকে পরীক্ষা করতে হবে। আমি নিয়মিত প্রকাশের মতো ব্যবহার করার চেষ্টা করেছি [a-zA-Z0-9_]+তবে এতে বিভিন্ন ভাষার বহু জাতীয়-নির্দিষ্ট অক্ষর অন্তর্ভুক্ত নেই (উদাঃ উমলাটস ইত্যাদি)। এই ধরনের চেক করার সর্বোত্তম উপায় কী?


আমি যদি আপনি
রেজেক্সের

উত্তর:


100

আপনি Path.GetInvalidPathCharsএবং থেকে অবৈধ অক্ষরের একটি তালিকা পেতে পারেন GetInvalidFileNameChars

ইউপিডি: কীভাবে এগুলিকে নিয়মিত অভিব্যক্তিতে ব্যবহার করতে হয় সে সম্পর্কে স্টিভ কুপারের পরামর্শ দেখুন ।

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


11
এটি প্রশ্নের উত্তর দেয় না; এখানে কেবলমাত্র বৈধ অক্ষরের সমন্বয়ে অনেকগুলি স্ট্রিং রয়েছে (যেমন "....", "কন", কয়েকশ অক্ষর দীর্ঘ স্ট্রিং) যা বৈধ ফাইলের নাম নয়।
ডোর হাই আর্চ

31
অন্য যে কেউ হতাশ হয়েছেন যে এমএস এই সক্ষমতার জন্য সিস্টেম স্তরের ফাংশন / এপিআই সরবরাহ করে না প্রতিটি বিকাশকারীকে তার নিজের সমাধান সমাধান করতে হবে? ভাবছেন যদি এর কোনও খুব ভাল কারণ আছে বা এমএস অংশের উপর কেবলমাত্র একটি তদারকি রয়েছে।
টমাস

@High আর্চ: প্রশ্ন "ইন সি # চেক যে ফাইলের নাম জন্য উত্তর দেখার সম্ভবত বৈধ (না যে উপস্থিত থাকে)"। (যদিও কিছু চালাক ছেলেরা এই প্রশ্নের পক্ষে এই প্রশ্নটি বন্ধ করে দিয়েছে ...)
মিমি মিমি মিমি

129

এমএসডিএন এর "ফাইলিং ডিরেক্টরি বা ডিরেক্টরি নামকরণ" থেকে উইন্ডোজের অধীনে আইনী ফাইলের নাম কী তা নিয়ে সাধারণ সম্মেলন এখানে দেওয়া হয়েছে:

আপনি বর্তমান কোড পৃষ্ঠায় যে কোনও অক্ষর ব্যবহার করতে পারেন (ইউনিকোড / এএনএসআই 127 এর উপরে) ব্যতীত:

  • < > : " / \ | ? *
  • যে অক্ষরগুলির পূর্ণসংখ্যার উপস্থাপনা 0-31 (এএসসিআইআই স্পেসের চেয়ে কম)
  • লক্ষ্য ফাইল সিস্টেমটি অনুমতি দেয় না এমন অন্য কোনও অক্ষর (বলুন, পিছনের সময়সীমা বা স্পেস)
  • ডসের যে কোনও নাম: সিওএন, পিআরএন, এউএক্স, নুল, সিওএম0, সিওএম 1, সিওএম 2, সিওএম 3, সিওএম 4, সিওএম 5, সিওএম 6, সিওএম 7, সিওএম 8, সিওএম 9, এলপিটি 4, এলপিটি 5, এলপিটি 6, এলপিটি 6, এলপিটি 6 LPT8, LPT9 (এবং AUX.txt ইত্যাদি এড়ানো)
  • ফাইলের নাম সমস্ত পিরিয়ড

চেক করার জন্য কিছু alচ্ছিক জিনিস:

  • ফাইল পাথগুলিতে (ফাইলের নাম সহ) 260 টির বেশি অক্ষর নাও থাকতে পারে (যা \?\উপসর্গটি ব্যবহার করে না )
  • ইউনিকোড ফাইল পাথ (ফাইলের নাম সহ) ব্যবহার করার সময় 32,000 টিরও বেশি অক্ষরের সাথে \?\(লক্ষ্য করুন যে উপসর্গটি ডিরেক্টরি উপাদানগুলি প্রসারিত করতে পারে এবং এটি 32,000 সীমা অতিক্রম করতে পারে)

8
সংরক্ষিত ফাইলের নাম অন্তর্ভুক্ত করার জন্য +1 - সেগুলি পূর্বের উত্তরে মিস হয়েছিল।
স্কেলরিয়ান

2
আপনি যদি "\\? \" সিনট্যাক্স ব্যবহার করেন তবে "AUX" একটি নিখুঁতভাবে ব্যবহারযোগ্য ফাইলের নাম। অবশ্যই, যে সিন্ট্যাক্সগুলি ব্যবহার করে না এমন প্রোগ্রামগুলির সাথে এটি ব্যবহার করার ক্ষেত্রে আসল সমস্যা আছে ... (এক্সপি তে পরীক্ষিত)
user9876

9
উপরে উল্লিখিত এই সমস্ত অবস্থার জন্য সঠিক রেজেক্স নীচের মতো:Regex unspupportedRegex = new Regex("(^(PRN|AUX|NUL|CON|COM[1-9]|LPT[1-9]|(\\.+)$)(\\..*)?$)|(([\\x00-\\x1f\\\\?*:\";|/<>])+)|(([\\. ]+)", RegexOptions.IgnoreCase);
কেন

4
@ কেনো আমি মনে করি আপনি এই রেজেজেলে একটি অতিরিক্ত খোলার বন্ধনী পেয়েছেন। "(^ (অন্তর্গত PRN | aux | NUL |, CON | এর COM [1-9] | LPT [1-9] | (\\ + +) $) (\\ .. *) $।?) | (([\\ x00 - \\ x1f \\\\ *: \ "; | / <>]) + +) | ([\\])।" আমার জন্য কাজ।
Wilky

4
আমি এই উত্তরে উল্লিখিত একই নিবন্ধটি পড়েছি এবং পরীক্ষার মাধ্যমে জানতে পেরেছি যে COM0 এবং LPT0 এছাড়াও অনুমোদিত নয়। @ ডিএলএফ এটি ফাইল ফাইলের সাথে কাজ করে যা '।' দিয়ে শুরু হয়:^(?!^(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)(?:\.*?(?!\.))[^\x00-\x1f\\?*:\";|\/<>]+(?<![\s.])$
মোজহসননগ্রার

67

জন্য নেট ফ্রেমওয়ার্ক পূর্বে 3.5 এই কাজ করা উচিত:

নিয়মিত এক্সপ্রেশন মেলানো আপনাকে কিছুটা উপায় পাওয়া উচিত। System.IO.Path.InvalidPathCharsধ্রুবকটি ব্যবহার করে এখানে একটি স্নিপেট রয়েছে ;

bool IsValidFilename(string testName)
{
    Regex containsABadCharacter = new Regex("[" 
          + Regex.Escape(System.IO.Path.InvalidPathChars) + "]");
    if (containsABadCharacter.IsMatch(testName)) { return false; };

    // other checks for UNC, drive-path format, etc

    return true;
}

.NET ফ্রেমওয়ার্কগুলির জন্য 3.0 এর পরে এটি কাজ করা উচিত:

http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars(v=vs.90).aspx

নিয়মিত এক্সপ্রেশন মেলানো আপনাকে কিছুটা উপায় পাওয়া উচিত। System.IO.Path.GetInvalidPathChars()ধ্রুবকটি ব্যবহার করে এখানে একটি স্নিপেট রয়েছে ;

bool IsValidFilename(string testName)
{
    Regex containsABadCharacter = new Regex("["
          + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]");
    if (containsABadCharacter.IsMatch(testName)) { return false; };

    // other checks for UNC, drive-path format, etc

    return true;
}

একবার আপনি এটি জানেন, আপনার আলাদা আলাদা ফর্ম্যাটগুলিও পরীক্ষা করা উচিত, যেমন c:\my\driveএবং\\server\share\dir\file.ext


এটি কি কেবল পথের পরীক্ষা করে না, ফাইল নাম নয়?
ইউজিন কাটজ

30
স্ট্রিং TheTheAreInuthorFileNameChars = নতুন স্ট্রিং (System.IO.Path.GetInuthorFileNameChars ()); Regex regFixFileName = new Regex ("[" + Regex.Esc (strTheseAreInuthorFileNameChars) + "]");
রাও

2
মানুষের কাছ থেকে একটি সামান্য গবেষণা বিস্ময়ের কাজ করবে। পরিবর্তনগুলি প্রতিবিম্বিত করতে আমি পোস্টটি আপডেট করেছি।
এরিক ফিলিপস

1
2 য় কোডের সংকলন হয় না। "চর থেকে [রূপরেখায় রূপান্তরিত করা যায় না]
পল হান্ট

1
@ আশকানমোবায়েেনখিয়াবানি: অবৈধপথচরগুলি অপ্রচলিত তবে গেটইনওয়েডিয়ালপথচারগুলি তা করে না।
ইভানএইচ

25

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


1
এটি কেবলমাত্র একমাত্র যা সমস্ত বাধা বিরুদ্ধে পরীক্ষা করে। অন্য উত্তরগুলি কেন এটির থেকে বেছে নেওয়া হচ্ছে?
ফাঁক

5
@ গ্যাপ কারণ এটি সর্বদা কার্যকর হয় না। উদাহরণস্বরূপ, CON অ্যাক্সেস করার চেষ্টা করা প্রায়শই সফল হবে, যদিও এটি আসল ফাইল নয়।
অ্যান্টিমনি

4
যদিও কোনও সম্ভাবনা রয়েছে সেখানে ব্যতিক্রম ছোঁড়ার স্মৃতি ওভারহেড এড়ানো সর্বদা ভাল।
ওভেন ব্ল্যাকার

2
এছাড়াও, আপনার এটি অ্যাক্সেস করার অনুমতি থাকতে পারে না; উদাহরণস্বরূপ এটি লেখার মাধ্যমে এটি পরীক্ষা করা, আপনি এটি পড়তে পারেন এমনকি যদি তা বিদ্যমান থাকে বা থাকবে।
কোডলকার

23

এই শ্রেণিটি ফাইলের নাম এবং পথগুলি পরিষ্কার করে; এটি পছন্দ করুন

var myCleanPath = PathSanitizer.SanitizeFilename(myBadPath, ' ');

কোডটি এখানে;

/// <summary>
/// Cleans paths of invalid characters.
/// </summary>
public static class PathSanitizer
{
    /// <summary>
    /// The set of invalid filename characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidFilenameChars;
    /// <summary>
    /// The set of invalid path characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidPathChars;

    static PathSanitizer()
    {
        // set up the two arrays -- sorted once for speed.
        invalidFilenameChars = System.IO.Path.GetInvalidFileNameChars();
        invalidPathChars = System.IO.Path.GetInvalidPathChars();
        Array.Sort(invalidFilenameChars);
        Array.Sort(invalidPathChars);

    }

    /// <summary>
    /// Cleans a filename of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizeFilename(string input, char errorChar)
    {
        return Sanitize(input, invalidFilenameChars, errorChar);
    }

    /// <summary>
    /// Cleans a path of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizePath(string input, char errorChar)
    {
        return Sanitize(input, invalidPathChars, errorChar);
    }

    /// <summary>
    /// Cleans a string of invalid characters.
    /// </summary>
    /// <param name="input"></param>
    /// <param name="invalidChars"></param>
    /// <param name="errorChar"></param>
    /// <returns></returns>
    private static string Sanitize(string input, char[] invalidChars, char errorChar)
    {
        // null always sanitizes to null
        if (input == null) { return null; }
        StringBuilder result = new StringBuilder();
        foreach (var characterToTest in input)
        {
            // we binary search for the character in the invalid set. This should be lightning fast.
            if (Array.BinarySearch(invalidChars, characterToTest) >= 0)
            {
                // we found the character in the array of 
                result.Append(errorChar);
            }
            else
            {
                // the character was not found in invalid, so it is valid.
                result.Append(characterToTest);
            }
        }

        // we're done.
        return result.ToString();
    }

}

1
: আপনার উত্তর ভাল এখানে পর্যাপ্ত জায়গা যেতে পারে stackoverflow.com/questions/146134/...
nawfal

22

এটি আমি ব্যবহার করি:

    public static bool IsValidFileName(this string expression, bool platformIndependent)
    {
        string sPattern = @"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\"";|/]+$";
        if (platformIndependent)
        {
           sPattern = @"^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?))\\)*[^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?$";
        }
        return (Regex.IsMatch(expression, sPattern, RegexOptions.CultureInvariant));
    }

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


4
পিপটারন রেজেক্স পিরিয়ড ক্যারেক্টার দিয়ে ফাইলগুলি শুরু করার অনুমতি দেয় না। তবে এমএসডিএন বলছে "একটি নামের প্রথম অক্ষর হিসাবে একটি সময়কাল নির্দিষ্ট করা গ্রহণযোগ্য example উদাহরণস্বরূপ," .temp ""। আমি .gitignore সঠিক ফাইলের নামটি তৈরি করতে "\ .. *" সরিয়ে ফেলব :)
yar_shukan

(আমি ছেড়ে যাওয়া পূর্ববর্তী মন্তব্যগুলি ক্রমবর্ধমানভাবে করেছি এবং এটি মুছে ফেলেছি) উত্তরের উত্তরটির তুলনায় এটি একটি ভাল কারণ এটি ".gitignore", "..এসডিএফ", '<' এবং '>' বা ইয়েনকে অনুমতি দেয় না সাইন ইন করুন, এবং শেষে স্থান বা পিরিয়ডের অনুমতি দেয় না (যা কেবলমাত্র বিন্দুর সমন্বয়ে থাকা নামগুলি অস্বীকার করে):@"^(?!(?:PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d)(?:\..+)?$)[^\x00-\x1F\xA5\\?*:\"";|\/<>]+(?<![\s.])$"
মজহোনসনেগ্র

আমি পরীক্ষিত সমস্ত ফাইলের জন্য এটি ব্যর্থ। এটি সি: \ উইন্ডোজ \ সিস্টেম 32 \ এমএসএক্সএমএল 6.ডিলের জন্য চালানো মিথ্যা রিপোর্ট করে।
ম্যাজিক্যান্ড্রে 1981

@ ম্যাজিক্যান্ড্রে ১৯৮১ আপনার সম্পূর্ণ ফাইলের পথ নয়, কেবলমাত্র ফাইলের নাম দেওয়া দরকার।
স্কট ডরম্যান

ঠিক আছে, তবে আমার পুরো পথটি বৈধ কিনা তা পরীক্ষা করে দেখতে হবে। আমি এখন একটি ভিন্ন সমাধান ব্যবহার।
ম্যাজিক্যান্ড্রে 1981

18

একটি কর্নার কেসটি মাথায় রাখার জন্য, যা আমাকে যখন অবাক করে দিয়েছিল আমি যখন প্রথমবার এটি সম্পর্কে জানতে পারি: উইন্ডোজ ফাইলের নামে স্থানের শীর্ষস্থানীয় অক্ষরগুলিকে অনুমতি দেয়! উদাহরণস্বরূপ, উইন্ডোতে ফাইলের নাম নীচে সমস্ত আইনী এবং স্বতন্ত্র (বিয়োগফলের উদ্ধৃতি) রয়েছে:

"file.txt"
" file.txt"
"  file.txt"

এটি থেকে একটি গ্রহণযোগ্য: একটি ফাইল নাম স্ট্রিং থেকে শীর্ষস্থানীয় / পশ্চাদ্বর্তিত স্থানকে ছাঁটাই করে এমন কোড লেখার সময় সতর্কতা ব্যবহার করুন।


10

ইউজিন কাটজ এর উত্তর সরলকরণ:

bool IsFileNameCorrect(string fileName){
    return !fileName.Any(f=>Path.GetInvalidFileNameChars().Contains(f))
}

অথবা

bool IsFileNameCorrect(string fileName){
    return fileName.All(f=>!Path.GetInvalidFileNameChars().Contains(f))
}

আপনি কি বোঝাতে চেয়েছিলেন: "ফিরুন! ফাইলের নাম.অন্য (চ => পথ.গেটআইনডাফাইল ফাইলনামচার্স () Cont ?
জ্যাক গ্রিফিন

@ জ্যাকগ্রিফিন অবশ্যই! আপনার মনোযোগের জন্য আপনাকে ধন্যবাদ।
tmt

যদিও এই কোডটি পড়তে খুব সুন্দর, তবে আমাদের আন্তঃসত্ত্বার আন্তঃসংযোগগুলি অ্যাকাউন্টে নেওয়া উচিত Path.GetInvalidFileNameChars। এখানে দেখে নিন: referencesource.microsoft.com/#mscorlib/system/io/path.cs,289 - আপনার প্রতিটি অক্ষরের জন্য fileName, এরে এর ক্লোন তৈরি করা হয়।
পাইটর জিয়ারহফার

"ডিডি: \\\\\ AAA যাচাই ..... AAAA"। বৈধ নয়, তবে আপনার কোডের জন্য এটি।
সিক্সিও প্যাস্তেসিও

8

মাইক্রোসফ্ট উইন্ডোজ: উইন্ডোজ কার্নেল পরিসীমা 1-31 (যেমন, 0x01-0x1F) এবং "*: <>? \ | অক্ষরের অক্ষর ব্যবহার নিষিদ্ধ করে যদিও এনটিএফএস প্রতিটি পথের উপাদানকে (ডিরেক্টরি বা ফাইলের নাম) 255 অক্ষর দীর্ঘ হতে দেয় এবং প্রায় 32767 অক্ষর পর্যন্ত দীর্ঘ পাথ, উইন্ডোজ কার্নেল কেবল 259 টি অক্ষর পর্যন্ত লম্বা পাথ সমর্থন করে Additionally অতিরিক্তভাবে, উইন্ডোজ এমএস-ডস ডিভাইসের নাম AUX, CLOCK $, COM1, COM2, COM3, COM4, ​​COM5, COM6, ব্যবহার করতে নিষেধ করে COM7, COM8, COM9, CON, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, NUL এবং PRN, পাশাপাশি কোনও বর্ধনের সাথে এই নামগুলি (উদাহরণস্বরূপ, AUX.txt) ব্যবহার করার সময় বাদে দীর্ঘ ইউএনসি পাথ (প্রাক্তন \। \ C: ul nul.txt বা \?: D: ux aux \ con)। (আসলে, ক্লক $ ব্যবহার করা যেতে পারে যদি কোনও এক্সটেনশন সরবরাহ করা হয়।) এই বিধিনিষেধগুলি কেবল উইন্ডোজ - লিনাক্স, উদাহরণস্বরূপ, "*: <> ব্যবহারের অনুমতি দেয়? \ | এমনকি এনটিএফএসেও।

সূত্র: http://en.wikedia.org/wiki/Filename


1
আমি "ক্লক named" নামের একটি ফাইল ঠিকঠাক তৈরি করতে পারি। উইন্ডোজ 7.
rory.ap

7

সমস্ত সম্ভাব্য অক্ষরকে স্পষ্টভাবে অন্তর্ভুক্ত করার পরিবর্তে, আপনি অবৈধ চরিত্রের উপস্থিতি যাচাই করতে একটি রেইজেক্স করতে পারেন এবং তারপরে একটি ত্রুটির কথা জানাতে পারেন। আদর্শভাবে আপনার অ্যাপ্লিকেশনটিতে ফাইলগুলির নাম ব্যবহারকারী হিসাবে ঠিক করা উচিত, এবং কেবল ত্রুটিপূর্ণভাবেই কান্না করা উচিত যদি এটি কোনও ত্রুটির মধ্য দিয়ে হোঁচট খায়।


6

প্রশ্নটি হ'ল আপনি নির্ধারণের চেষ্টা করছেন যে কোনও পাথের নাম আইনী উইন্ডোজ পাথ কিনা, বা কোডটি যে সিস্টেমে চলছে সেখানে এটি আইনী কিনা ? আমি মনে করি যে পরবর্তীটি আরও গুরুত্বপূর্ণ, তাই ব্যক্তিগতভাবে, আমি সম্ভবত পুরো পথটি পচন করতে এবং ফাইলটির মধ্যে থাকা ডিরেক্টরিটি তৈরি করার জন্য _mkdir ব্যবহার করার চেষ্টা করব, তারপরে ফাইলটি তৈরি করার চেষ্টা করব।

এই পথে আপনি কেবল জানেন না যে পাথটিতে কেবল বৈধ উইন্ডোজ অক্ষর রয়েছে, তবে যদি এটি প্রকৃতপক্ষে এমন কোনও পথকে উপস্থাপন করে যা এই প্রক্রিয়াটি দ্বারা লেখা যেতে পারে।


6

আমি ব্যতিক্রম ছোঁড়া ছাড়াই ফাইলনেমে অবৈধ অক্ষরগুলি থেকে মুক্তি পেতে এটি ব্যবহার করি:

private static readonly Regex InvalidFileRegex = new Regex(
    string.Format("[{0}]", Regex.Escape(@"<>:""/\|?*")));

public static string SanitizeFileName(string fileName)
{
    return InvalidFileRegex.Replace(fileName, string.Empty);
}

5

এছাড়াও কন, পিআরএন, অক্স, এনএল, সিওএম # এবং আরও কয়েকজন কখনও কোনও এক্সটেনশন সহ কোনও ডিরেক্টরিতে কোনও আইনি ফাইল নাম নয়।


1
এটি সত্যের অর্ধেক মাত্র। ক্রিয়েটফাইলে ইউনিকোড সংস্করণ ("\\? \" দিয়ে ফাইলের নাম উপস্থাপন করা) কল করা থাকলে আপনি এই নামের সাথে ফাইল তৈরি করতে পারেন।
ওয়ার্নার হেনজে

এই বিবৃতিটি অসম্পূর্ণ এবং এলপিটিকে মিস করেছে #
টমাস ওয়েলারের

4

অন্যান্য উত্তরগুলির পরিপূরক করতে এখানে অতিরিক্ত কয়েকটি প্রান্তের কেস যা আপনি বিবেচনা করতে চাইতে পারেন তা এখানে।

  • আপনি যদি কোনও ফাইলটিতে এমন একটি ওয়ার্কবুক সংরক্ষণ করেন যার নামটিতে '[' বা ']' অক্ষর রয়েছে তবে এক্সেলের সমস্যা হতে পারে। বিশদ জানতে http://support.microsoft.com/kb/215205 দেখুন ।

  • শেয়ারপয়েন্টে সম্পূর্ণ অতিরিক্ত বিধিনিষেধ রয়েছে। বিস্তারিত জানার জন্য http://support.microsoft.com/kb/905231 দেখুন ।


3

এমএসডিএন থেকে , এমন অক্ষরের একটি তালিকা রয়েছে যা অনুমোদিত নয়:

নিম্নলিখিত ব্যতীত ইউনিকোড অক্ষর এবং বর্ধিত অক্ষর সেট (128-255) এর অক্ষর সহ একটি নামের জন্য বর্তমান কোড পৃষ্ঠায় প্রায় কোনও অক্ষর ব্যবহার করুন:

  • নিম্নলিখিত সংরক্ষিত অক্ষরগুলির অনুমতি নেই: <>: "/ \ |? *
  • যে অক্ষরের পূর্ণসংখ্যার উপস্থাপনা শূন্য থেকে 31 এর মধ্যে থাকে তা অনুমোদিত নয়।
  • লক্ষ্য ফাইল সিস্টেমটি অনুমতি দেয় না এমন অন্য কোনও অক্ষর।

2

এছাড়াও গন্তব্য ফাইল সিস্টেমটি গুরুত্বপূর্ণ।

এনটিএফএসের অধীনে কিছু ডিরেক্টরি নির্দিষ্ট ডিরেক্টরিতে তৈরি করা যায় না। EG $ রুটে বুট করুন


2
অবশ্যই এটি কোনও এনটিএফএসের নামকরণের নিয়মের কারণে নয়, তবে কেবলমাত্র নামে ডাকা একটি ফাইল $Bootডিরেক্টরিতে বিদ্যমান?
খ্রিস্টান হাইটার

2

এটি একটি ইতিমধ্যে উত্তর দেওয়া প্রশ্ন, তবে কেবল "অন্যান্য বিকল্পগুলির" জন্য, এখানে একটি আদর্শ নয় one

(আদর্শহীন কারণ প্রবাহ নিয়ন্ত্রণ হিসাবে ব্যতিক্রমগুলি ব্যবহার করা একটি "খারাপ জিনিস", সাধারণত)

public static bool IsLegalFilename(string name)
{
    try 
    {
        var fileInfo = new FileInfo(name);
        return true;
    }
    catch
    {
        return false;
    }
}

আপনার উদাহরণটি কোনও সিওএন ফাইলের জন্য কাজ করে নি (সি: \ টেম্পিচার \ সিওএন)।
tcbrazil

তবে 'সি: \ টেম্পে \ সিওএন' একটি বৈধ ফাইলের নাম নয়? কেন হবে না?
মার্ক এ। ডোনোহো

@ মার্কিআইভি - না, এটি বৈধ নয়। উপরের সমস্ত উত্তর এবং মন্তব্য পড়ুন, বা নিজে চেষ্টা করে দেখুন।
rory.ap

@ জার, "/ উদাহরণ" আইনী নয়, তবুও আপনার পদ্ধতিটি ফিরে আসে true
rory.ap

আআআআআআ ... আমি 'কন' অংশটি মিস করেছি। নামটি নিজেই একটি স্ট্রিং দৃষ্টিকোণ থেকে বৈধ (যা আমি উল্লেখ করছিলাম), তবে আমি এখন দেখতে পাচ্ছি সিএন একটি সংরক্ষিত নাম, এটি একটি উইন্ডোজ দৃষ্টিকোণ থেকে এটি বৈধ নয়। আমার খারাপ।
মার্ক এ। ডোনহো

2

নিয়মিত প্রকাশগুলি এই পরিস্থিতির জন্য অতিমাত্রায় দক্ষ। আপনি এবং এর String.IndexOfAny()সাথে একত্রে পদ্ধতিটি ব্যবহার করতে পারেন ।Path.GetInvalidPathChars()Path.GetInvalidFileNameChars()

এছাড়াও লক্ষ করুন যে দুটি Path.GetInvalidXXX()পদ্ধতিই একটি অভ্যন্তরীণ অ্যারের ক্লোন করে এবং ক্লোনটি ফিরে দেয়। সুতরাং আপনি যদি এটি প্রচুর পরিমাণে করতে যাচ্ছেন (হাজার হাজার এবং কয়েকবার) আপনি পুনরায় ব্যবহারের জন্য অবৈধ অক্ষর অ্যারের একটি অনুলিপি ক্যাশে করতে পারেন।


2

যদি আপনি কেবলমাত্র আপনার ফাইলের নাম / পাথের স্ট্রিংয়ের কোনও অবৈধ অক্ষর রয়েছে কিনা তা Split()খতিয়ে দেখার চেষ্টা করছেন, আমি খুঁজে পেয়েছি দ্রুততম পদ্ধতিটি যেখানে কোনও অবৈধ অক্ষর আছে সেখানেই ফাইলের নামটি একটি অংশে বিভক্ত করা উচিত। যদি ফলাফলটি কেবল 1 টি অ্যারে হয় তবে কোনও অবৈধ অক্ষর নেই। :-)

var nameToTest = "Best file name \"ever\".txt";
bool isInvalidName = nameToTest.Split(System.IO.Path.GetInvalidFileNameChars()).Length > 1;

var pathToTest = "C:\\My Folder <secrets>\\";
bool isInvalidPath = pathToTest.Split(System.IO.Path.GetInvalidPathChars()).Length > 1;

আমি লিনকপ্যাডে 1,000,000 বার একটি ফাইল / পাথ নামের উপরে উল্লিখিত এই এবং অন্যান্য পদ্ধতিগুলি চালনার চেষ্টা করেছি।

ব্যবহার করা Split()হয় মাত্র 850 ডলার।

ব্যবহার Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidPathChars())) + "]")প্রায় 6 সেকেন্ড।

আরও জটিল নিয়মিত এক্সপ্রেশনগুলি আরও খারাপ, যেমন Pathফাইলের নাম পাওয়ার জন্য ক্লাসে বিভিন্ন পদ্ধতি ব্যবহার করে এবং তাদের অভ্যন্তরীণ বৈধতাটি কাজটি করতে দেয় (সম্ভবত ব্যতিক্রম হ্যান্ডলিংয়ের ওভারহেডের কারণে) options

মঞ্জুর যে এটি প্রায়শই আপনার 1 মিলিয়ন ফাইলের নাম যাচাইকরণের প্রয়োজন হয় না, সুতরাং এই পদ্ধতিগুলির বেশিরভাগ ক্ষেত্রেই একক পুনরাবৃত্তি ঠিক আছে। তবে আপনি যদি কেবল অবৈধ চরিত্রের সন্ধান করেন তবে এটি এখনও বেশ দক্ষ এবং কার্যকর।


1

ফাইলের নামটি অনেক দীর্ঘ এবং প্রাক উইন্ডোজ 10 পরিবেশে চলতে থাকলে এই উত্তরগুলির মধ্যে অনেকগুলি কাজ করবে না। একইভাবে, আপনি পিরিয়ডগুলির সাথে কী করতে চান তা সম্পর্কে চিন্তাভাবনা করুন - নেতৃত্ব দেওয়া বা অনুদানের অনুমতি দেওয়া প্রযুক্তিগতভাবে বৈধ, তবে আপনি যদি ফাইলটি যথাক্রমে দেখতে বা মুছতে অসুবিধা না চান তবে সমস্যা তৈরি করতে পারেন।

এটি একটি বৈধ ফাইলের নাম যাচাই করার জন্য তৈরি করা একটি বৈধতা বৈশিষ্ট্য।

public class ValidFileNameAttribute : ValidationAttribute
{
    public ValidFileNameAttribute()
    {
        RequireExtension = true;
        ErrorMessage = "{0} is an Invalid Filename";
        MaxLength = 255; //superseeded in modern windows environments
    }
    public override bool IsValid(object value)
    {
        //http://stackoverflow.com/questions/422090/in-c-sharp-check-that-filename-is-possibly-valid-not-that-it-exists
        var fileName = (string)value;
        if (string.IsNullOrEmpty(fileName)) { return true;  }
        if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) > -1 ||
            (!AllowHidden && fileName[0] == '.') ||
            fileName[fileName.Length - 1]== '.' ||
            fileName.Length > MaxLength)
        {
            return false;
        }
        string extension = Path.GetExtension(fileName);
        return (!RequireExtension || extension != string.Empty)
            && (ExtensionList==null || ExtensionList.Contains(extension));
    }
    private const string _sepChar = ",";
    private IEnumerable<string> ExtensionList { get; set; }
    public bool AllowHidden { get; set; }
    public bool RequireExtension { get; set; }
    public int MaxLength { get; set; }
    public string AllowedExtensions {
        get { return string.Join(_sepChar, ExtensionList); } 
        set {
            if (string.IsNullOrEmpty(value))
            { ExtensionList = null; }
            else {
                ExtensionList = value.Split(new char[] { _sepChar[0] })
                    .Select(s => s[0] == '.' ? s : ('.' + s))
                    .ToList();
            }
    } }

    public override bool RequiresValidationContext => false;
}

এবং পরীক্ষা

[TestMethod]
public void TestFilenameAttribute()
{
    var rxa = new ValidFileNameAttribute();
    Assert.IsFalse(rxa.IsValid("pptx."));
    Assert.IsFalse(rxa.IsValid("pp.tx."));
    Assert.IsFalse(rxa.IsValid("."));
    Assert.IsFalse(rxa.IsValid(".pp.tx"));
    Assert.IsFalse(rxa.IsValid(".pptx"));
    Assert.IsFalse(rxa.IsValid("pptx"));
    Assert.IsFalse(rxa.IsValid("a/abc.pptx"));
    Assert.IsFalse(rxa.IsValid("a\\abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c:abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c<abc.pptx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
    rxa = new ValidFileNameAttribute { AllowedExtensions = ".pptx" };
    Assert.IsFalse(rxa.IsValid("abc.docx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
}

1

আমার প্রচেষ্টা:

using System.IO;

static class PathUtils
{
  public static string IsValidFullPath([NotNull] string fullPath)
  {
    if (string.IsNullOrWhiteSpace(fullPath))
      return "Path is null, empty or white space.";

    bool pathContainsInvalidChars = fullPath.IndexOfAny(Path.GetInvalidPathChars()) != -1;
    if (pathContainsInvalidChars)
      return "Path contains invalid characters.";

    string fileName = Path.GetFileName(fullPath);
    if (fileName == "")
      return "Path must contain a file name.";

    bool fileNameContainsInvalidChars = fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1;
    if (fileNameContainsInvalidChars)
      return "File name contains invalid characters.";

    if (!Path.IsPathRooted(fullPath))
      return "The path must be absolute.";

    return "";
  }
}

এটি নিখুঁত নয় কারণ Path.GetInvalidPathCharsফাইল এবং ডিরেক্টরি নামগুলিতে অবৈধ অক্ষরের সম্পূর্ণ সেটটি ফেরত দেয় না এবং অবশ্যই আরও অনেক সূক্ষ্মতা রয়েছে।

সুতরাং আমি এই পদ্ধতিটি পরিপূরক হিসাবে ব্যবহার করি:

public static bool TestIfFileCanBeCreated([NotNull] string fullPath)
{
  if (string.IsNullOrWhiteSpace(fullPath))
    throw new ArgumentException("Value cannot be null or whitespace.", "fullPath");

  string directoryName = Path.GetDirectoryName(fullPath);
  if (directoryName != null) Directory.CreateDirectory(directoryName);
  try
  {
    using (new FileStream(fullPath, FileMode.CreateNew)) { }
    File.Delete(fullPath);
    return true;
  }
  catch (IOException)
  {
    return false;
  }
}

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

আপনি মৌলিক বৈধতা যাচাই করার জন্য প্রথম পদ্ধতিটিও ব্যবহার করতে পারেন, এবং তারপরে পথটি ব্যবহার করার সময় ব্যতিক্রমগুলি সাবধানতার সাথে পরিচালনা করতে পারেন।


0

আমি কেবল পথটি ব্যবহার করার পরামর্শ দিই etGetFullPath ()

string tagetFileFullNameToBeChecked;
try
{
  Path.GetFullPath(tagetFileFullNameToBeChecked)
}
catch(AugumentException ex)
{
  // invalid chars found
}

এই উত্তরটি কীভাবে বর্তমান সমস্যা সমাধানে
ওপিকে

এমএসডিএন-তে অগমেন্টামেক্সেপশনের জন্য ডকটি দেখুন, এটি পড়েছে: পাথ শূন্য দৈর্ঘ্যের একটি স্ট্রিং, কেবলমাত্র সাদা স্থান রয়েছে, বা এক বা একাধিক অবৈধ অক্ষর রয়েছে গেটইনফোর্ডপ্যাথচারসে সংজ্ঞায়িত। -অর- সিস্টেম পরম পথটি পুনরুদ্ধার করতে পারেনি।
টনি সান

তত্ত্ব (দস্তাবেজ অনুসারে) এটি কাজ করা উচিত, সমস্যা কমপক্ষে। নেট কোর 3.1 এ থাকলেও তা হয় না।
মিশেল জানসন

0

আমি কারও কাছ থেকে এই ধারণা পেয়েছি। - কে জানি না। ওএস ভারী উত্তোলন করতে দিন।

public bool IsPathFileNameGood(string fname)
{
    bool rc = Constants.Fail;
    try
    {
        this._stream = new StreamWriter(fname, true);
        rc = Constants.Pass;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Problem opening file");
        rc = Constants.Fail;
    }
    return rc;
}

0

এই চেক

static bool IsValidFileName(string name)
{
    return
        !string.IsNullOrWhiteSpace(name) &&
        name.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
        !Path.GetFullPath(name).StartsWith(@"\\.\");
}

আউট অবৈধ অক্ষর (সঙ্গে নাম ফিল্টার <>:"/\|?*এবং হওয়া ASCII 0-31), সেইসাথে সংরক্ষিত ডস ডিভাইস ( CON, NUL, COMx)। এটি নেতৃত্বাধীন স্পেস এবং সমস্ত-ডট-নামগুলির সাথে সামঞ্জস্য রাখে Path.GetFullPath। (শীর্ষস্থানীয় স্পেস সহ ফাইল তৈরি করা আমার সিস্টেমে সফল হয়)।


উইন্ডোজ 7 এ পরীক্ষিত নেট নেট ফ্রেমওয়ার্ক 4.7.1 ব্যবহার করা হয়েছে।


0

স্ট্রিংয়ে অবৈধ অক্ষরগুলি যাচাই করার জন্য একটি লাইনার:

public static bool IsValidFilename(string testName) => !Regex.IsMatch(testName, "[" + Regex.Escape(new string(System.IO.Path.InvalidPathChars)) + "]");

0

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


-1

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

\ / : * ? " < > |

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


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