.NET- এ কোনও ফাইলের জন্য অ্যাক্সেস অস্বীকার করা হয়েছে কীভাবে আপনি সহজেই পরীক্ষা করতে পারেন?


103

মূলত, আমি ফাইলটি খোলার চেষ্টা করার আগে আমার খোলার অধিকার আছে কিনা তা যাচাই করতে চাই; আমার প্রয়োজন না থাকলে আমি এই চেকটির জন্য চেষ্টা / ক্যাপচার ব্যবহার করতে চাই না। আমি হাতের আগে যাচাই করতে পারি এমন কোনও ফাইল অ্যাক্সেস সম্পত্তি আছে কি?


4
আমি ট্যাগটি পরিবর্তন করলে ক্যাপশন: "আমি সংশোধন করছি"। মজা করছি না.
জোয়েল কোহোর্ন

6
সম্মত- আমি আশা করি একটি ট্রাইওপেন (অর্থাত্ চেষ্টা-পার্সের ধরণ) থাকত।
ত্রিস্তান

উত্তর:


160

আমি অতীতে এই অসংখ্যবার করেছি এবং প্রায় প্রতিবারই এটি করেছি আমি চেষ্টাও ভুল করেছিলাম।

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

এর অর্থ হ'ল আপনার চেক সত্ত্বেও যদি ফাইল অনুমতি বা অস্তিত্ব খারাপ থাকে তবে আপনাকে এখনও ব্যতিক্রমগুলি পরিচালনা করতে সক্ষম হতে হবে। আপনি আগাম ফাইলের অনুমতি যাচাই করে বা না রেখে ব্যতিক্রম হ্যান্ডলিং কোডটি প্রয়োজনীয় । ব্যতিক্রম হ্যান্ডলিং কোড অস্তিত্ব বা অনুমতি চেকগুলির কার্যকারিতা সমস্ত সরবরাহ করে । অতিরিক্ত হিসাবে, যদিও এই জাতীয় ব্যতিক্রম হ্যান্ডলারগুলি ধীর বলে পরিচিত, তবে এটি মনে রাখা গুরুত্বপূর্ণ যে ডিস্ক i / o এমনকি ধীর ... অনেক ধীর ... এবং এক্সজিস্টস () ফাংশনটিতে কল করা বা অনুমতিগুলি পরীক্ষা করা অতিরিক্ত ট্রিপকে বাধ্য করবে ফাইল সিস্টেম আউট।

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


5
হুবহু এটি একটি রেসের শর্তের একটি দুর্দান্ত উদাহরণ।
পাওয়ারলর্ড

4
কোরো: আপনাকে যেভাবেই হোক ব্যর্থতার জন্য খারাপ অনুমতিগুলি পরিচালনা করতে সক্ষম হতে হবে এবং এটি প্রাথমিক চেকটিকে অপ্রয়োজনীয় এবং অপব্যয়কারী করে তোলে।
জোয়েল কোহর্ন

4
প্রাথমিক চেকটি সাধারণ সুনির্দিষ্ট ত্রুটিগুলি কৌতুকপূর্ণভাবে পরিচালনা করতে সহায়তা করতে পারে - নির্দিষ্ট কারণগুলির সাথে নির্দিষ্ট ব্যতিক্রমের বৈশিষ্ট্যের সাথে মিল রেখে তুলনা করা প্রায়শই সহজ। চেষ্টা / ধরা এখনও বাধ্যতামূলক থাকে।
পিটারচেন

5
এটি খোলার চেষ্টা করার আগে "এই ফাইলটি খোলার অধিকার আমার আছে কিনা তা কীভাবে পরীক্ষা করতে হবে" এই প্রশ্নের উত্তর এই উত্তর দেয় না। কেসটি খুব ভালভাবে হতে পারে, যদি সেই সময়ে অনুমতিটির অনুমতি না দেওয়া হয় তবে সফ্টওয়্যারটি ফাইলটি পড়ার চেষ্টা করবে না, এমনকি অনুমতি চেক করার পরেও অনুমতিটি খুব ভালভাবে দেওয়া যেতে পারে।
ট্রায়ঙ্কো

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

25

অনুরূপ সমস্যা নিয়ে এখানে অন্য যে কেউ আসছেন তাদের জন্য দ্রুত টিপস:

ড্রপবক্সের মতো ওয়েব সিঙ্ক্রোনাইজেশন অ্যাপ্লিকেশনগুলির জন্য নজর রাখুন। "নেট" ব্যবহারের বিবৃতিটি (ডিসপোজ প্যাটার্ন)। নেট এ বিভক্ত হয়ে ভেবে আমি মাত্র 2 ঘন্টা ব্যয় করেছি।

অবশেষে আমি বুঝতে পেরেছি যে ড্রপবক্স ক্রমাগত ফাইলগুলি সেগুলিকে সিঙ্ক করার জন্য পটভূমিতে পড়ছে এবং লিখছে।

আমার ভিজ্যুয়াল স্টুডিও প্রকল্পগুলির ফোল্ডারটি কোথায় অবস্থিত তা অনুমান করুন? অবশ্যই "আমার ড্রপবক্স" ফোল্ডারের ভিতরে।

সুতরাং আমি যখন আমার অ্যাপ্লিকেশনটি ডিবাগ মোডে চালিত করছিলাম তখন এটি যে ফাইলগুলি পড়ছিল এবং লিখছিল সেগুলি ক্রমাগত ড্রপবক্স দ্বারা ড্রপবক্স সার্ভারের সাথে সিঙ্ক করার জন্য অ্যাক্সেস করা হত। এটি লকিং / অ্যাক্সেসের দ্বন্দ্ব সৃষ্টি করেছিল।

তাই কমপক্ষে আমি এখন জানি যে আমার আরও বেশি শক্তিশালী ফাইল ওপেন ফাংশন (যেমন ট্রাইওপেন () যা একাধিক প্রচেষ্টা করবে) দরকার। আমি অবাক হয়েছি এটি ইতিমধ্যে কাঠামোর একটি অন্তর্নির্মিত অংশ নয়।

[হালনাগাদ]

এখানে আমার সহায়ক ফাংশন:

/// <summary>
/// Tries to open a file, with a user defined number of attempt and Sleep delay between attempts.
/// </summary>
/// <param name="filePath">The full file path to be opened</param>
/// <param name="fileMode">Required file mode enum value(see MSDN documentation)</param>
/// <param name="fileAccess">Required file access enum value(see MSDN documentation)</param>
/// <param name="fileShare">Required file share enum value(see MSDN documentation)</param>
/// <param name="maximumAttempts">The total number of attempts to make (multiply by attemptWaitMS for the maximum time the function with Try opening the file)</param>
/// <param name="attemptWaitMS">The delay in Milliseconds between each attempt.</param>
/// <returns>A valid FileStream object for the opened file, or null if the File could not be opened after the required attempts</returns>
public FileStream TryOpen(string filePath, FileMode fileMode, FileAccess fileAccess,FileShare fileShare,int maximumAttempts,int attemptWaitMS)
{
    FileStream fs = null;
    int attempts = 0;

    // Loop allow multiple attempts
    while (true)
    {
        try
        {
            fs = File.Open(filePath, fileMode, fileAccess, fileShare);

            //If we get here, the File.Open succeeded, so break out of the loop and return the FileStream
            break;
        }
        catch (IOException ioEx)
        {
            // IOExcception is thrown if the file is in use by another process.

            // Check the numbere of attempts to ensure no infinite loop
            attempts++;
            if (attempts > maximumAttempts)
            {
                // Too many attempts,cannot Open File, break and return null 
                fs = null;
                break;
            }
            else
            {
                // Sleep before making another attempt
                Thread.Sleep(attemptWaitMS);

            }

        }

    }
    // Reutn the filestream, may be valid or null
    return fs;
}

4
@ যেভাবে আমার মনে হয় আপনি প্রশ্নটি সঠিকভাবে পড়েন নি তিনি চেষ্টা করতে চেষ্টা এড়াতে চান।
রবিশা

10
@ রবিশা, আপনি কি জোয়েলের শীর্ষের ভোট পড়েছেন? জোয়েল যেমন বলেছে, "পরিবর্তে আপনি যা করেন তা কেবল ফাইলটি খোলার চেষ্টা করুন এবং ব্যর্থ হলে এটি ব্যতিক্রমটিকে পরিচালনা করবেন" । আপনি কিছু এড়ানো যায় না এই বিষয়টি আপনার পছন্দ না হওয়ার কারণে দয়া করে নীচে নামাবেন না।
অ্যাশ

কোডের জন্য ধন্যবাদ! একটি জিনিস, ব্যবহার করে ব্যবহার করা আরও ভাল eg উদাহরণস্বরূপ তাজিমের উত্তরটি এখানে দেখুন
সেল

আপনি ফাইলপ্রবাহটি ফেরত দিয়েছেন তবে তারপরে কলকারীকে usingএটি ব্যবহার করতে হবে ...
সেল

@ সেল - usingএখানে কাজ করবে না। ব্যবহার ব্লক শেষে, fsজোর করে বন্ধ করা হবে। আপনি কলারকে একটি ক্লোজড (এত অকেজো) ফাইল স্ট্রিম দেবেন!
টুলমেকারস্টেভ

4

আপনি যে সমাধানটি সন্ধান করছেন তা এখানে

var fileIOPermission = new FileIOPermission(FileIOPermissionAccess.Read,
                                            System.Security.AccessControl.AccessControlActions.View,
                                            MyPath);

if (fileIOPermission.AllFiles == FileIOPermissionAccess.Read)
{
    // Do your thing here...
}

এটি সমস্ত ফাইলের পাথের জন্য ভিউ ভিত্তিক পড়ার একটি নতুন অনুমতি তৈরি করে তারপরে এটি ফাইল অ্যাক্সেস পঠনের সমান কিনা তা পরীক্ষা করে।


3

প্রথমত, জোয়েল কোহুর্ন কী বলেছিলেন।

এছাড়াও: আপনার এমন অনুমানগুলি যাচাই করা উচিত যা নীচে আপনার প্রয়োজন না থাকলে চেষ্টা / ধরা ব্যবহার এড়াতে আপনার আকাঙ্ক্ষার অন্তর্গত। যুক্তি এড়ানোর সাধারণ কারণ যা ব্যতিক্রমগুলির উপর নির্ভর করে ( Exceptionঅবজেক্ট তৈরি করা খারাপভাবে সম্পাদন করে) সম্ভবত কোনও ফাইল খোলার কোডের সাথে প্রাসঙ্গিক নয়।

আমি মনে করি আপনি যদি এমন একটি পদ্ধতি লিখে List<FileStream>থাকেন যা ডিরেক্টরি সাবট্রিতে প্রতিটি ফাইল খোলার মাধ্যমে একটি জনকে জনপ্রিয় করে তোলে এবং আপনি তাদের প্রচুর সংখ্যক অ্যাক্সেসযোগ্য হওয়ার প্রত্যাশা করেছিলেন তবে আপনি কোনও ফাইল খোলার চেষ্টা করার আগে ফাইল অনুমতি পরীক্ষা করতে চাইতে পারেন যাতে আপনি না অনেক ব্যতিক্রম পেতে। তবে আপনি এখনও ব্যতিক্রমটি পরিচালনা করতে চাই। এছাড়াও, যদি আপনি এমন কোনও পদ্ধতি লিখে থাকেন তবে আপনার প্রোগ্রামের ডিজাইনে সম্ভবত মারাত্মক কিছু আছে।


-1
public static bool IsFileLocked(string filename)
        {
            bool Locked = false;
            try
            {
                FileStream fs =
                    File.Open(filename, FileMode.OpenOrCreate,
                    FileAccess.ReadWrite, FileShare.None);
                fs.Close();
            }
            catch (IOException ex)
            {
                Locked = true;
            }
            return Locked;
        }

-3
public static FileStream GetFileStream(String filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, ref int attempts, int attemptWaitInMilliseconds)
{            
    try
    {
         return File.Open(filePath, fileMode, fileAccess, fileShare);
    }
    catch (UnauthorizedAccessException unauthorizedAccessException)
    {
        if (attempts <= 0)
        {
            throw unauthorizedAccessException;
        }
        else
        {
            Thread.Sleep(attemptWaitInMilliseconds);
            attempts--;
            return GetFileStream(filePath, fileMode, fileAccess, fileShare, ref attempts, attemptWaitInMilliseconds);
        }
    }
}

8
-1: "নিক্ষেপ;" ব্যবহার করুন "অননুমোদিত অ্যাক্সেসএক্সসেপশন নিক্ষেপ করবেন না"; আপনি আপনার স্ট্যাক ট্রেস হারাচ্ছেন।
জন স্যান্ডার্স

attemptsরেফ দ্বারা কেন পাস করা হয়? ওটা কোন অর্থ প্রকাশ করে না. উভয়ই ন্যায়বিচারের <=পরিবর্তে পরীক্ষা করে না ==
কনরাড রুডল্ফ

4
@ জন: ভাল, এক্ষেত্রে পুনরাবৃত্ত কলটির (গভীরভাবে বাসা বাঁধা ) স্ট্যাক ট্রেস হারিয়ে ফেলা বাঞ্ছনীয় তাই আমি মনে করি যে এই দৃষ্টিতে throw exআসলে সঠিক কাজ করা উচিত।
কনরাড রুডল্ফ

4
@ কনরাড: @ রুডজাইটিস: আমি -১ এর জন্য আমার কারণটি পরিবর্তন করছি। এটি "থ্রো প্রাক্তন" দ্বারা স্ট্যাকের ক্ষতি করার চেয়ে খারাপ। আপনি স্ট্যাকের গভীরতা আসলে গুরুত্বপূর্ণ যখন এমন সময়ে পুনরাবৃত্তির মাধ্যমে অতিরিক্ত স্ট্যাকের স্তরকে কৃত্রিমভাবে প্ররোচিত করে আপনি স্ট্যাকটি স্ক্রু করছেন। এটি পুনরাবৃত্তি সমস্যা নয়, পুনরাবৃত্তিযোগ্য সমস্যা।
জন স্যান্ডার্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.