ডিরেক্টরিটি মুছে ফেলা যায় না ডিরেক্টরিটি মুছে ফেলা (পথ, সত্য)


383

আমি .NET 3.5 ব্যবহার করছি, এটি ব্যবহার করে একটি ডিরেক্টরি পুনরাবৃত্তভাবে মুছে ফেলার চেষ্টা করছি:

Directory.Delete(myPath, true);

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

যাইহোক, আমি মাঝে মধ্যে এটি পেতে:

System.IO.IOException: The directory is not empty.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
    at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
    ...

আমি কখনও অবাক হই না যে পদ্ধতিটি মাঝে মাঝে ছুঁড়ে মারে, তবে পুনরাবৃত্তি হওয়া সত্য হলে এই বিশেষ বার্তাটি পেয়ে আমি অবাক হয়েছি। (আমি জানি ডিরেক্টরিটি খালি নয়))

অ্যাক্সেসওয়েলেশন এক্সসেপশনের পরিবর্তে আমি এটি দেখতে পাবার কোনও কারণ আছে?


13
আপনি অ্যাক্সেসভিওলেশন এক্সসেপশন দেখতে পাবেন না - এটি অবৈধ পয়েন্টার অপারেশনের জন্য, ডিস্ক অ্যাক্সেসের জন্য নয়।
জো হোয়াইট

1
এটি কেবল ডিরেক্টরি খালি নয়, ওপেন ফাইল হ্যান্ডলগুলি বা অন্য কোনও কিছুর বাইরে আইও ইস্যুতে কিছু প্রকারের বলে মনে হচ্ছে। আমি পুনরাবৃত্তির মোছার বিকল্পটি ব্যবহার করে চেষ্টা করব, তারপরে আইওএক্সেপশনের জন্য, কোনও খোলা ফাইল হ্যান্ডলগুলি অনুসন্ধান এবং বন্ধ করে তারপরে আবার চেষ্টা করুন। আছে: যে সম্পর্কে একটি আলোচনা এখানে শেষ stackoverflow.com/questions/177146/...
ড্যান Csharpster

উত্তর:


231

সম্পাদকের দ্রষ্টব্য: যদিও এই উত্তরে কিছু দরকারী তথ্য রয়েছে তবে এটি কার্যকারিতা সম্পর্কে ভুল Directory.Delete। এই উত্তরটির জন্য মন্তব্যগুলি এবং এই প্রশ্নের অন্যান্য উত্তরগুলি দয়া করে পড়ুন।


আমি আগে এই সমস্যায় পড়েছিলাম।

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

আপনার প্রকল্পে কেবল এই কোডটি স্লাপ করুন।

public static void DeleteDirectory(string target_dir)
{
    string[] files = Directory.GetFiles(target_dir);
    string[] dirs = Directory.GetDirectories(target_dir);

    foreach (string file in files)
    {
        File.SetAttributes(file, FileAttributes.Normal);
        File.Delete(file);
    }

    foreach (string dir in dirs)
    {
        DeleteDirectory(dir);
    }

    Directory.Delete(target_dir, false);
}

এছাড়াও, আমার জন্য আমি ব্যক্তিগতভাবে মেশিনের যে অংশগুলি মুছে ফেলার অনুমতি দেওয়া হয়েছে সেগুলিতে একটি বিধিনিষেধ যুক্ত করেছি কারণ আপনি কি চান যে কেউ এই ফাংশনটিতে C:\WINDOWS (%WinDir%)বা কল করতে চান C:\


117
এটা অপদার্থ. ডিরেক্টরি.ডিলেট (মাইপাথ, সত্য) একটি ওভারলোড যা ডিরেক্টরি কাঠামোর মধ্যে থাকা সমস্ত ফাইল মুছে দেয়। আপনি যদি ভুল হতে চান তবে রায়ান এস এর উত্তরটি দিয়ে ভুল করুন।
সিগ টলেরেঞ্জা

35
+1 কারণ যদিও ডিরেক্টরী.ডিলিট () তার উপ-ডিরেক্টরিগুলির মধ্যে ফাইলগুলি মুছে ফেলে (পুনরাবৃত্ত = সত্য সহ), এটি একটি "আইওএক্সেপশন: ডিরেক্টরি খালি নয়" যদি সাব-ডিরেক্টরি বা ফাইলগুলির মধ্যে কেবল একটির পাঠযোগ্য হয়। সুতরাং এই সমাধানটি ডিরেক্টরি থেকে আরও ভাল কাজ করে
e ডিলিট

17
আপনার বিবৃতি যা Directory.Delete(path, true)ফাইল মোছা না ভুল। এমএসডিএন এমএসডিএন.মাইক্রোসফট. com
কনস্ট্যান্টিন স্পিরিন

20
-1 কেউ দয়া করে একটি স্পষ্ট চিহ্নিতকারী রাখতে পারেন যে এই পদ্ধতির বৈধতা সন্দেহজনক। যদি Directory.Delete(string,bool)ব্যর্থ হয় তবে কিছু লক করা হয়েছে বা ভুলভাবে প্রবেশ করা হয়েছে এবং এমন সমস্যার সমাধানের জন্য কোনও আকারই ফিট করে না। লোকেরা তাদের প্রসঙ্গে এই সমস্যাটির সমাধান করতে হবে এবং আমরা সমস্যার প্রতি প্রতিটি ধারণা বড় আকারের ছোঁড়া বাড়িয়ে তুলছি (পুনরায় চেষ্টা এবং ব্যতিক্রম গিলে) এবং একটি ভাল ফলাফলের প্রত্যাশায়।
রুবেন বারটেলিংক

37
আপনার ডিরেক্টরিটি মুছতে যদি অন্য ফোল্ডারে শর্টকাট / প্রতীকী লিঙ্ক থাকে - এই পদ্ধতির বিষয়ে সাবধান থাকুন - আপনি প্রত্যাশিত পরে আরও মুছে ফেলতে পারেন
চাণাক্য

182

আপনি যদি ডিরেক্টরিটি পুনরাবৃত্তভাবে মুছে ফেলার চেষ্টা করছেন এবং এক্সপ্লোরারটিতে aডিরেক্টরিটি a\bখোলা আছে, bমুছে ফেলা হবে তবে আপনি aযখন গিয়ে দেখবেন তখন এটি খালি থাকলেও আপনি 'ডিরেক্টরিটি খালি নয়' ত্রুটিটি পেয়ে যাবেন। যে কোনও অ্যাপ্লিকেশনের বর্তমান ডিরেক্টরি (এক্সপ্লোরার সহ) ডিরেক্টরিতে একটি হ্যান্ডেল ধরে রাখে । আপনি যখন কল করবেন তখন Directory.Delete(true)এটি নীচে থেকে মুছে ফেলা হবে:, bতারপরে abএক্সপ্লোরার এ যদি খোলা থাকে, এক্সপ্লোরার ডিলিটেশন সনাক্ত করে b, ডিরেক্টরিটি উপরের দিকে পরিবর্তন করবে cd ..এবং খোলা হ্যান্ডলগুলি পরিষ্কার করবে। ফাইল সিস্টেম যেহেতু অবিচ্ছিন্নভাবে পরিচালনা করে, Directory.Deleteএক্সপ্লোরারের সাথে দ্বন্দ্বের কারণে অপারেশন ব্যর্থ হয়।

অসম্পূর্ণ সমাধান

এক্সপ্লোরারকে ডিরেক্টরি হ্যান্ডেলটি প্রকাশের সময় দেওয়ার জন্য বর্তমান থ্রেডটিতে বাধা দেওয়ার ধারণাটি সহ আমি মূলত নিম্নলিখিত সমাধানটি পোস্ট করেছি।

// incomplete!
try
{
    Directory.Delete(path, true);
}
catch (IOException)
{
    Thread.Sleep(0);
    Directory.Delete(path, true);
}

তবে এটি কেবল তখনই কাজ করে যদি খোলা ডিরেক্টরিটি আপনি মুছে ফেলা ডিরেক্টরিটির তাত্ক্ষণিক শিশু। যদি a\b\c\dএক্সপ্লোরারে খোলা থাকে এবং আপনি এটি ব্যবহার করেন a, এই কৌশলটি মোছার পরে dএবং ব্যর্থ হবে c

আরও কিছুটা ভাল সমাধান

এক্সপ্লোরারটিতে নিম্ন-স্তরের ডিরেক্টরিগুলির মধ্যে একটি খোলা থাকলেও এই পদ্ধতিটি গভীর ডিরেক্টরি কাঠামো মোছার বিষয়টি পরিচালনা করবে।

/// <summary>
/// Depth-first recursive delete, with handling for descendant 
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
    foreach (string directory in Directory.GetDirectories(path))
    {
        DeleteDirectory(directory);
    }

    try
    {
        Directory.Delete(path, true);
    }
    catch (IOException) 
    {
        Directory.Delete(path, true);
    }
    catch (UnauthorizedAccessException)
    {
        Directory.Delete(path, true);
    }
}

আমাদের নিজের উপর পুনরাবৃত্তি অতিরিক্ত কাজ সত্ত্বেও, আমরা এখনও পথে চলতে পারে তা পরিচালনা UnauthorizedAccessExceptionকরতে হবে। এটি মুছে ফেলা হচ্ছে না যে প্রথম মোছার প্রচেষ্টা দ্বিতীয়টির পক্ষে সফল হয়েছে, সফল, বা যদি এটি কেবলমাত্র সময় ব্যয় করে নিক্ষেপ / একটি ব্যতিক্রম ধরা দিয়ে দেয় যা ফাইল সিস্টেমটিকে ধরা দেয়।

আপনি Thread.Sleep(0)শুরুর দিকে একটি যোগ করে সাধারণ অবস্থার অধীনে নিক্ষিপ্ত এবং ধরা পড়া ব্যতিক্রম সংখ্যা হ্রাস করতে সক্ষম হতে পারেনtry ব্লকের । অতিরিক্তভাবে, ভারী সিস্টেমের লোডের অধীনে, আপনি উভয় প্রয়াসেই উড়ে যেতে Directory.Deleteএবং ব্যর্থ হতে পারেন এমন ঝুঁকি রয়েছে । এই সমাধানটিকে আরও দৃ rec় পুনরাবৃত্তি মোছার জন্য একটি প্রাথমিক পয়েন্ট বিবেচনা করুন।

সাধারণ উত্তর

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

দৃust় ফাইল পুনরাবৃত্তি কোড ফাইল ফাইলের অনেক জটিলতা অ্যাকাউন্টে নিতে হবে।

এই নিরীহ বিবৃতিটি, কেবলমাত্র এনটিএফএসের রেফারেন্স ডকুমেন্টেশনের লিঙ্ক সহ সরবরাহ করা উচিত, আপনার চুলগুলি দাঁড়ানো উচিত।

( সম্পাদনা করুন : প্রচুর This এই উত্তরের মূলত কেবলমাত্র প্রথম, অসম্পূর্ণ সমাধান ছিল))


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

1
এটি কীভাবে এবং কেন কাজ করে তা আমি জানতে পারি না তবে এটি ফাইলের বৈশিষ্ট্যগুলি নির্ধারণ করার সময় এবং আমার নিজের পুনরাবৃত্ত ফাংশনটি লেখার সময় এটি আমার পক্ষে কাজ করে।
স্টিলগার

1
@ কার্লোস লিয়ু কারণ এটি "এক্সপ্লোরারকে ডিরেক্টরি হ্যান্ডেলটি প্রকাশের সুযোগ দিচ্ছে"
দিমিত্রি গনচর

4
যা ঘটছে তা হ'ল সিস্টেমটি এক্সপ্লোরারকে "ডিরেক্টরি হ্যান্ডেলটি ছেড়ে দিতে" বলে, তারপরে ডিরেক্টরিটি মুছে ফেলার চেষ্টা করে। যদি ডিরেক্টরিটির হ্যান্ডেলটি সময় মতো মুছে না দেওয়া হয়, তবে একটি ব্যতিক্রম উত্থাপিত হয় এবং catchব্লকটি কার্যকর করা হয় (ইতিমধ্যে, এক্সপ্লোরার এখনও ডিরেক্টরিটি মুক্তি দিচ্ছে, কারণ এটি না করার জন্য কোনও আদেশ প্রেরণ করা হয়নি)। কলটি প্রয়োজনীয় Thread.Sleep(0)বা নাও হতে পারে, কারণ catchব্লকটি ইতিমধ্যে সিস্টেমটিকে আরও খানিকটা সময় দিয়েছে তবে এটি কম খরচে কিছুটা অতিরিক্ত সুরক্ষা সরবরাহ করে। এর পরে, Deleteডিরেক্টরিটি ইতিমধ্যে প্রকাশিত ডিরেক্টরি সহ বলা হয়।
জাকারি নিয়েবল

1
@ পান্ডাওয়ুড আসলে এই ঘুম (100) আমার পক্ষে কাজ করেছিল। ঘুম (0) কাজ করে না। কী চলছে এবং কীভাবে এটি সঠিকভাবে সমাধান করা যায় সে সম্পর্কে আমার কোনও ধারণা নেই। মানে, এটি যদি সার্ভার লোডের উপর নির্ভর করে এবং ভবিষ্যতে 300 বা 400 হওয়া উচিত? কীভাবে তা জানব। অবশ্যই অন্য একটি সঠিক উপায় হতে হবে ...
রোমান

43

আরও যাওয়ার আগে, আপনার নিয়ন্ত্রণে থাকা নিম্নলিখিত কারণগুলি যাচাই করুন:

  • আপনার প্রক্রিয়াটির বর্তমান ডিরেক্টরি হিসাবে ফোল্ডারটি সেট করা আছে? যদি হ্যাঁ, প্রথমে এটি অন্য কোনওটিতে পরিবর্তন করুন।
  • আপনি কি এই ফোল্ডারটি থেকে কোনও ফাইল (বা একটি ডিএলএল লোড করেছেন) খুললেন? (এবং এটি বন্ধ / আনলোড করতে ভুলে গেছেন)

অন্যথায়, আপনার নিয়ন্ত্রণের বাইরে নিম্নলিখিত বৈধ কারণগুলির জন্য পরীক্ষা করুন:

  • সেই ফোল্ডারে কেবল পঠনযোগ্য হিসাবে চিহ্নিত ফাইল রয়েছে।
  • আপনার কাছে সেই ফাইলগুলির কয়েকটি মুছতে অনুমতি নেই।
  • এক্সপ্লোরার বা অন্য অ্যাপে ফাইল বা সাবফোল্ডার খোলা আছে is

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

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

  • অনুসন্ধান সূচক
  • বিরোধী ভাইরাস
  • ব্যাকআপ সফ্টওয়্যার

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

private static void DeleteRecursivelyWithMagicDust(string destinationDir) {
    const int magicDust = 10;
    for (var gnomes = 1; gnomes <= magicDust; gnomes++) {
        try {
            Directory.Delete(destinationDir, true);
        } catch (DirectoryNotFoundException) {
            return;  // good!
        } catch (IOException) { // System.IO.IOException: The directory is not empty
            System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes);

            // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic
            Thread.Sleep(50);
            continue;
        }
        return;
    }
    // depending on your use case, consider throwing an exception here
}

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

আমার অ্যাপ্লিকেশন দ্বারা উত্পাদিত একটি অভ্যন্তরীণ ডেটা ফোল্ডারের জন্য আমার উত্সাহজনক ব্যর্থতা ছিল,% লোকাল অ্যাপ ডেটা% এর অধীনে, সুতরাং আমার বিশ্লেষণটি এরকম হয়:

  1. ফোল্ডারটি কেবলমাত্র আমার অ্যাপ্লিকেশন দ্বারা নিয়ন্ত্রিত হয় এবং ব্যবহারকারীর কাছে and ফোল্ডারের ভিতরে জিনিসগুলি কেবল পঠনযোগ্য বা অ্যাক্সেসযোগ্য হিসাবে চিহ্নিত করার কোনও যুক্তিসঙ্গত কারণ নেই, তাই আমি কেসটি হ্যান্ডেল করার চেষ্টা করি না।

  2. সেখানে কোনও মূল্যবান ব্যবহারকারীর দ্বারা তৈরি জিনিস নেই, সুতরাং ভুলভাবে কিছু জোর করে মুছে ফেলার কোনও ঝুঁকি নেই।

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

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

  5. আমি পুনরায় চেষ্টাগুলি 500 মিমি (50 * 10) এ সীমাবদ্ধ করতে বেছে নিয়েছি। এটি একটি স্বেচ্ছাসেবী প্রান্তিক যা অনুশীলনে কাজ করে; আমি চেয়েছিলাম যে প্রান্তিক সংক্ষিপ্ত পরিমাণটি সংক্ষিপ্ত হোক যাতে ব্যবহারকারীরা অ্যাপটি বন্ধ না করে এই ভেবে যে এটির প্রতিক্রিয়া বন্ধ হয়ে গেছে। অন্যদিকে, অপরাধীর জন্য আমার ফোল্ডারটি প্রক্রিয়াকরণ শেষ করতে আধ সেকেন্ড সময় প্রচুর পরিমাণে। অন্যান্য এসও উত্তরগুলি বিচার করে যা কখনও কখনও এমনকি Sleep(0)গ্রহণযোগ্য বলে মনে হয়, খুব কম ব্যবহারকারী কখনও একক পুনরায় চেষ্টা করার চেয়ে বেশি অভিজ্ঞতা অর্জন করতে পারেন।

  6. আমি প্রতি 50 মিটারে আবার চেষ্টা করি যা অন্য এক স্বেচ্ছাসেবী সংখ্যা। আমি মনে করি যে কোনও ফাইলটি মুছে ফেলার চেষ্টা করার পরে যদি (যদি সূচিযুক্ত, পরীক্ষিত) প্রসেস করা হচ্ছে তবে আমার ক্ষেত্রে প্রসেসটি সম্পন্ন হওয়ার আশা করার জন্য 50 মিমি সঠিক সময়টি। এছাড়াও, 50 মিমি যথেষ্ট ছোট যা একটি নজরে পড়ার মতো ধীরগতির কারণ নয়; আবার Sleep(0)অনেক ক্ষেত্রে যথেষ্ট মনে হয়, তাই আমরা বেশি দেরি করতে চাই না।

  7. কোডটি কোনও আইও ব্যতিক্রমগুলিতে পুনরায় চেষ্টা করে। আমি সাধারণত% লোকাল অ্যাপডেটা% অ্যাক্সেসের কোনও ব্যতিক্রম প্রত্যাশা করি না, তাই আমি সরলতা বেছে নিয়েছি এবং বৈধ ব্যতিক্রম ঘটলে 500 মিমি দেরির ঝুঁকি গ্রহণ করেছি। আমি আবার চেষ্টা করতে চাই ঠিক সেই ব্যতিক্রমটি সনাক্ত করার উপায়ও বের করতে চাইনি।


7
পিপিএস কয়েক মাস পরে, আমি জানাতে পেরে খুশি যে এই (কিছুটা উন্মাদ) কোডের টুকরোটি সমস্যার সমাধান করেছে solved এই সমস্যা সম্পর্কে সমর্থন অনুরোধগুলি শূন্যের নিচে (প্রতি সপ্তাহে প্রায় 1-2 থেকে)।
আন্দ্রে তারানসভ

1
যদিও এটি এখানে আরও শক্তিশালী এবং কম 'এটি এখানে রয়েছে; আপনার জন্য স্ট্যাকওভারফ্লো.com / a / 7518831 / 11635 এর চেয়ে নিখুঁত সমাধান , আমার জন্য একই প্রযোজ্য - কাকতালীয়ভাবে প্রোগ্রামিং - যত্ন সহকারে পরিচালনা করুন। আপনার কোডটিতে অঙ্কিত একটি দরকারী বিষয় হ'ল আপনি যদি পুনরায় চেষ্টা করতে চলেছেন তবে আপনাকে বিবেচনা করা দরকার যে শেষ চেষ্টা থেকে ডিরেক্টরিটি 'গেছে' কিনা তার দ্ব্যর্থতার সাথে আপনি দৌড়ে এসেছেন [এবং একজন নিয়াগ Directory.Existsগার্ড হবে) এটি সমাধান করুন না]]
রুবেন বারটেলিংক

1
এটি ভালবাসুন ... আমি কী করছি তা জানি না যে এটি আমার জন্য সর্বদা ব্যথার বিষয় ... তবে এটি এমন নয় যে আমার এক্সপ্লোরারটিতে ডিরেক্টরিটি খোলা আছে ... এটি সম্পর্কে ইন্টারনেটে খুব বেশি আলোড়ন নেই not বা কম-কম বাগ ... কমপক্ষে আমার এবং অ্যান্ড্রে এর সাথে যোগাযোগ করার একটি উপায় আছে :)
টিসিসি

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

2
@ নোপাড়া আপনার তুলনা করার দরকার নেই; যদি আমরা লুপের বাইরে চলে যাই তবে আমরা ব্যর্থ হয়েছি। এবং হ্যাঁ, অনেক ক্ষেত্রে আপনি ব্যতিক্রম ছুঁড়ে ফেলতে চান, তারপরে স্ট্যাকটি আপ করার জন্য যথাযথ ত্রুটি হ্যান্ডলিং কোড যুক্ত করুন, সম্ভবত কোনও ব্যবহারকারী-দৃশ্যমান বার্তা রয়েছে।
আন্দ্রে তারানসভ 16

18

আধুনিক অ্যাসিঙ্ক উত্তর

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

public static async Task<bool> TryDeleteDirectory(
   string directoryPath,
   int maxRetries = 10,
   int millisecondsDelay = 30)
{
    if (directoryPath == null)
        throw new ArgumentNullException(directoryPath);
    if (maxRetries < 1)
        throw new ArgumentOutOfRangeException(nameof(maxRetries));
    if (millisecondsDelay < 1)
        throw new ArgumentOutOfRangeException(nameof(millisecondsDelay));

    for (int i = 0; i < maxRetries; ++i)
    {
        try
        {
            if (Directory.Exists(directoryPath))
            {
                Directory.Delete(directoryPath, true);
            }

            return true;
        }
        catch (IOException)
        {
            await Task.Delay(millisecondsDelay);
        }
        catch (UnauthorizedAccessException)
        {
            await Task.Delay(millisecondsDelay);
        }
    }

    return false;
}

ইউনিট টেস্ট

এই পরীক্ষাগুলি একটি লক করা ফাইল Directory.Deleteকীভাবে ব্যর্থ হতে পারে এবং TryDeleteDirectoryউপরের পদ্ধতিটি কীভাবে সমস্যার সমাধান করে তার একটি উদাহরণ দেখায় ।

[Fact]
public async Task TryDeleteDirectory_FileLocked_DirectoryNotDeletedReturnsFalse()
{
    var directoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    var subDirectoryPath = Path.Combine(Path.GetTempPath(), "SubDirectory");
    var filePath = Path.Combine(directoryPath, "File.txt");

    try
    {
        Directory.CreateDirectory(directoryPath);
        Directory.CreateDirectory(subDirectoryPath);

        using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
        {
            var result = await TryDeleteDirectory(directoryPath, 3, 30);
            Assert.False(result);
            Assert.True(Directory.Exists(directoryPath));
        }
    }
    finally
    {
        if (Directory.Exists(directoryPath))
        {
            Directory.Delete(directoryPath, true);
        }
    }
}

[Fact]
public async Task TryDeleteDirectory_FileLockedThenReleased_DirectoryDeletedReturnsTrue()
{
    var directoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    var subDirectoryPath = Path.Combine(Path.GetTempPath(), "SubDirectory");
    var filePath = Path.Combine(directoryPath, "File.txt");

    try
    {
        Directory.CreateDirectory(directoryPath);
        Directory.CreateDirectory(subDirectoryPath);

        Task<bool> task;
        using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
        {
            task = TryDeleteDirectory(directoryPath, 3, 30);
            await Task.Delay(30);
            Assert.True(Directory.Exists(directoryPath));
        }

        var result = await task;
        Assert.True(result);
        Assert.False(Directory.Exists(directoryPath));
    }
    finally
    {
        if (Directory.Exists(directoryPath))
        {
            Directory.Delete(directoryPath, true);
        }
    }
}

"আধুনিক" বলতে কী বোঝাতে চেয়েছেন আপনি কি তা প্রসারিত করতে পারেন? আপনার পদ্ধতির সুবিধা কি? অন্যেরা কেন আপনার মতে ভুল?
টিনিআরাকুন

1
অন্যরাও ভুল নয়। তারা কেবল পুরানো এপিআই-এর মতো ব্যবহার করে Thread.Sleepযা আপনার আজ এড়ানো উচিত এবং পরিবর্তে async/ awaitসহ ব্যবহার করা উচিত Task.Delay। এটি বোধগম্য, এটি একটি খুব পুরানো প্রশ্ন।
মুহাম্মদ রেহান সা Saeedদ

এই পদ্ধতির ভিবি.নেটে কাজ হবে না (কমপক্ষে খুব আক্ষরিক লাইন-ফর-লাইন রূপান্তরের সাথে নয়)BC36943 'Await' cannot be used inside a 'Catch' statement, a 'Finally' statement, or a 'SyncLock' statement.
amonroejj

@amonroejj আপনি অবশ্যই একটি পুরানো সংস্করণ ব্যবহার করছেন। তা স্থির ছিল।
মুহাম্মদ রেহান সাইদ

if (!Directory.Exists(directoryPath)) { return true; } await Task.Delay(millisecondsDelay); ডিরেক্টরিটি সত্যি না হওয়া পর্যন্ত অপেক্ষা করতে সত্য ফিরে পাওয়ার পরিবর্তে সামান্য উন্নতি
fuchs777

16

একটি গুরুত্বপূর্ণ বিষয় যা উল্লেখ করা উচিত (আমি এটি একটি মন্তব্য হিসাবে যুক্ত করেছি তবে আমাকে অনুমতি দেওয়া হচ্ছে না) হ'ল ওভারলোডের আচরণটি নেট নেট থেকে 3.5। নেট 4.0 এ পরিবর্তিত হয়েছে।

Directory.Delete(myPath, true);

.NET 4.0 থেকে শুরু করে এটি ফোল্ডারে ফাইলগুলি মুছে ফেলে তবে 3.5 এ নয়। এটি এমএসডিএন ডকুমেন্টেশনেও দেখা যায়।

.NET 4.0

নির্দিষ্ট ডিরেক্টরি মুছে ফেলা হয় এবং যদি নির্দেশিত হয় তবে ডিরেক্টরিতে যে কোনও উপ-ডিরেক্টরি এবং ফাইল মুছে ফেলা হয়

.NET 3.5

একটি খালি ডিরেক্টরি মুছে ফেলে এবং যদি নির্দেশিত হয় তবে ডিরেক্টরিতে কোনও সাব-ডিরেক্টরি এবং ফাইল মুছে ফেলা হয় ।


3
আমার মনে হয় এটি কেবলমাত্র একটি ডকুমেন্টেশন পরিবর্তন ... এটি যদি কেবল একটি "খালি ডিরেক্টরি" মুছে দেয় তবে ডিরেক্টরিতে ফাইলগুলি 2 ° পরামিতি মোছার অর্থ কী? যদি এটি খালি থাকে তবে কোনও ফাইল নেই ...
পিসু

আমি ভীত আপনি ভুল ধরে নিচ্ছেন। আমি উভয় ফ্রেমওয়ার্ক সংস্করণ সহ কোডটি পরীক্ষার পরে এটি পোস্ট করেছি। 3.5 এ একটি খালি খালি ফোল্ডার মোছা একটি ব্যতিক্রম ছুঁড়ে দেবে।
জেটাটোর

15

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

22 টি ধরা পড়েছিল, আমি মুছে ফেলার আগে এটির পিতা-মাতার কাছে একটি সাধারণ পরিবর্তন ডিরেক্টরি তৈরি করেছি।


6
+1 এখন এমন কিছু আছে যা ডিরেক্টরিতে এমএসডিএন করে। ডিলিটটি উল্লেখ করে!
রুবেন বারটেলিংক

3
পুরো উত্স কোড নমুনা নিয়ে কোন চূড়ান্ত সমাধান সম্পর্কে কাজ করছে?
কিকিনেট

11

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

Process.Start("cmd.exe", "/c " + @"rmdir /s/q C:\Test\TestDirectoryContainingReadOnlyFiles"); 

(মুহূর্তের জন্য একটি সেমিডি উইন্ডোতে আগুন না ছোঁড়ার জন্য কিছুটা পরিবর্তন করুন, যা পুরো ইন্টারনেটে পাওয়া যায়)


আমাদের সাথে ভাগ করে নিতে পেরে ভাল লাগলেও আপনি কী নেট থেকে অনুসন্ধান করার জন্য আমাদেরকে অনুরোধ করার পরিবর্তে, সিএমডি উইন্ডো চালানো রোধ করার জন্য প্রয়োজনীয় কিছুটা পরিবর্তন অন্তর্ভুক্ত করার মতো দয়া করবেন?
থান্ডারগ্রি

এটি কাজ করে না। একই পরিস্থিতিতে যেখানে আমি কমান্ড প্রম্পট বা এক্সপ্লোরার থেকে ফাইলটি মুছতে পারি, এই কোডটি ব্যবহার করে rmdir কল করতে প্রস্থান কোড 145 দেয় যা "ডিরেক্টরিটি খালি নয়" তে অনুবাদ করে। এটা তোলে ডিরেক্টরির খালি কিন্তু এখনও জায়গায় খুব, ছেড়ে ঠিক Directory.Delete ( "", সত্য) -এর মত
কেভিন Coulombe

@ কেভিন কুলম্ব, হুম ... আপনি কি নিশ্চিত যে আপনি / গুলি / কিউ সুইচগুলি ব্যবহার করছেন?
পীযূষ সনি

1
@ কেভিনকৌলম্ব্বে: হ্যাঁ, এটি অবশ্যই সেই COM উপাদান হতে হবে। আমি যখন সরল পুরানো সি # দিয়ে চেষ্টা করি তখন এটি কাজ করে এবং এটি ভিতরে থাকা ফাইলগুলির সাথে ডিরেক্টরিটি মুছবে (কেবল পঠনযোগ্য বা কেবল পঠনযোগ্য নয়)।
পীযূষ সোনি

5
ফ্রেমওয়ার্কে কী হওয়া উচিত তার জন্য যদি আপনি বাহ্যিক উপাদানগুলির উপর নির্ভর করতে শুরু করেন তবে এটি "আদর্শের চেয়ে কম" ধারণা কোজ এটি আর বহনযোগ্য নয় (বা আরও কঠিন)। এক্সি না থাকলে কী হবে? বা / বিকল্প পরিবর্তন হয়েছে? যদি জেরেমি এডওয়ার্ডসের সমাধানটি কাজ করে তবে এটি পছন্দ করা উচিত আইএমএইচও
ফ্রেঞ্চোন

11

আপনি চালিয়ে ত্রুটিটি পুনরুত্পাদন করতে পারেন:

Directory.CreateDirectory(@"C:\Temp\a\b\c\");
Process.Start(@"C:\Temp\a\b\c\");
Thread.Sleep(1000);
Directory.Delete(@"C:\Temp\a\b\c");
Directory.Delete(@"C:\Temp\a\b");
Directory.Delete(@"C:\Temp\a");

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

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

যদি আপনি মুছুন ফাংশনের উত্স কোডটি দেখুন ( http: //references Source.microsoft.com/#mscorlib/system/io/directory.cs) আপনি দেখতে পাবেন এটি নেটিভ Win32Native.RemoveDirectory ফাংশনটি ব্যবহার করে। এই না-অপেক্ষা আচরণ এখানে উল্লেখ করা হয়:

মুছে ফেলা নির্দেশিকা ফাংশনটি ডিলিট করার জন্য একটি ডিরেক্টরি চিহ্নিত করে marks সুতরাং, ডিরেক্টরিটির শেষ হ্যান্ডেলটি বন্ধ না হওয়া অবধি ডিরেক্টরিটি সরানো হবে না।

( http://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(vvv..85).aspx )

ঘুম এবং পুনরায় চেষ্টা করা সমাধান। সিএফ রিয়াসল এর সমাধান।


8

এক্সপ্লোরার শেলটিতে সক্ষম হয়েও ব্যবহারকারী প্রোফাইল ডিরেক্টরিগুলি (সি: \ ডকুমেন্টস এবং সেটিংসে) মোছার ক্ষেত্রে আমার কাছে সেই অদ্ভুত অনুমতি সংক্রান্ত সমস্যা ছিল।

File.SetAttributes(target_dir, FileAttributes.Normal);
Directory.Delete(target_dir, false);

কোনও ডিরেক্টরিতে "ফাইল" অপারেশন কী করে তা আমার কাছে কোনও ধারণা রাখে না, তবে আমি জানি যে এটি কাজ করে এবং এটি আমার পক্ষে যথেষ্ট!


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

3

এই উত্তরটির উপর ভিত্তি করে: https://stackoverflow.com/a/1703799/184528 । আমার কোডের সাথে পার্থক্যটি হ'ল আমরা যখন প্রয়োজনীয় তখন ডিরেক্টরি অনেকগুলি ডিলিট সাব-ডাইরেক্টরি এবং ফাইলগুলিকে পুনরুক্তি করি lete ডিলিট প্রথম প্রচেষ্টাতে ব্যর্থ হয় (যা উইন্ডোজ এক্সপ্লোরার ডিরেক্টরিতে দেখার কারণে ঘটতে পারে)।

    public static void DeleteDirectory(string dir, bool secondAttempt = false)
    {
        // If this is a second try, we are going to manually 
        // delete the files and sub-directories. 
        if (secondAttempt)
        {
            // Interrupt the current thread to allow Explorer time to release a directory handle
            Thread.Sleep(0);

            // Delete any files in the directory 
            foreach (var f in Directory.GetFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
                File.Delete(f);

            // Try manually recursing and deleting sub-directories 
            foreach (var d in Directory.GetDirectories(dir))
                DeleteDirectory(d);

            // Now we try to delete the current directory
            Directory.Delete(dir, false);
            return;
        }

        try
        {
            // First attempt: use the standard MSDN approach.
            // This will throw an exception a directory is open in explorer
            Directory.Delete(dir, true);
        }
        catch (IOException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        }
        catch (UnauthorizedAccessException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        } 
    }

সুতরাং যদি এটি একটি ফোল্ডারটি মুছে ফেলা হয় UnauthorizedAccessException? এটা ঠিক আবার ফেলে দিতে হবে। এবং আবার. এবং আবার ... কারণ প্রতিটি সময় এটি গিয়ে catchআবার ফাংশনটি কল করে। এ Thread.Sleep(0);আপনার অনুমতি পরিবর্তন করে না। এটি কেবল ত্রুটিটি লগ করা উচিত এবং বিনীতভাবে ব্যর্থ হওয়া উচিত that এবং এই লুপটি ঠিক ততক্ষণ চালিয়ে যাবে যতক্ষণ না (সাব- ডিরেক্টরি) খোলা থাকে - এটি প্রোগ্রামিকভাবে এটি বন্ধ করে না। যতক্ষণ না এই জিনিসগুলি খোলা থাকে ততক্ষণ আমরা কী এটির জন্য এটি প্রস্তুত রাখতে প্রস্তুত? একটি ভাল উপায় আছে কি?
vapcguy

যদি এটি থাকে তবে UnauthorizedAccessExceptionএটি প্রতিটি ফাইল ম্যানুয়ালি মুছে ফেলার চেষ্টা করবে। সুতরাং এটি ডিরেক্টরি কাঠামোতে প্রবেশ করে অগ্রগতি অব্যাহত রেখেছে। হ্যাঁ, সম্ভাব্যভাবে প্রতিটি ফাইল এবং ডিরেক্টরি একই ব্যতিক্রম ছুঁড়ে ফেলবে, তবে এটি কেবল কারণেই ঘটতে পারে কারণ এক্সপ্লোরার এতে একটি হ্যান্ডেল ধরে রাখে (দেখুন stackoverflow.com/a/1703799/184528 ) আমি "ট্রাই অ্যাগেইন" কে "সেকেন্ড ট্রাই" তে পরিবর্তন করব আরও স্পষ্ট করতে।
cdiggins

আরও সাফল্যের সাথে উত্তর দেওয়ার জন্য, এটি "সত্য" কেটে যায় এবং একটি ভিন্ন কোড পাথ কার্যকর করে।
সিডিগিংস

ঠিক আছে, আপনার সম্পাদনাটি দেখেছেন, তবে আমার বক্তব্য ফাইলগুলি মুছে ফেলার সাথে নয়, ডিরেক্টরিটি মুছে ফেলার সাথে। আমি এমন কিছু কোড লিখেছিলাম যেখানে আমি প্রয়োজনীয়ভাবে করতে পারিProcess.Kill() কোনও ফাইল লক হয়ে থাকতে পারে এমন কোনও প্রক্রিয়াতে এবং ফাইলগুলি মুছি। আমি যে সমস্যাটি চালাচ্ছি তা হ'ল এমন একটি ডিরেক্টরি মুছে ফেলা হয় যেখানে সেই ফাইলগুলির মধ্যে একটি এখনও খোলা ছিল ( স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ৪১৮৪১90৯০ / দেখুন দেখুন )। সুতরাং এই লুপটির মধ্য দিয়ে ফিরে যাওয়া, এটি আর কী করছে তা বিবেচনাধীন নয়, যদি এটি Directory.Delete()সেই ফোল্ডারে আবারও করে, হ্যান্ডেলটি প্রকাশ না করা যায় তবে এটি ব্যর্থ হবে।
vapcguy

এবং UnauthorizedAccessExceptionফাইলগুলি মুছে ফেলার পরেও এটি ঘটতে পারে (ধরে নেওয়াও এটি অনুমোদিত হয়েছিল, কারণ সেই Directory.Delete()কোডটিতে পৌঁছানোর জন্য এটি ব্যর্থ হয়েছে ) আপনাকে যাদুকরীভাবে ডিরেক্টরিটি মুছে ফেলার অনুমতি দেয় না।
vapcguy

3

উপরের সমাধানগুলি আমার পক্ষে ভাল কাজ করেছে। নীচে হিসাবে @ryascl সমাধানের সম্পাদিত সংস্করণটি ব্যবহার করে আমি শেষ করেছি:

    /// <summary>
    /// Depth-first recursive delete, with handling for descendant 
    /// directories open in Windows Explorer.
    /// </summary>
    public static void DeleteDirectory(string path)
    {
        foreach (string directory in Directory.GetDirectories(path))
        {
            Thread.Sleep(1);
            DeleteDir(directory);
        }
        DeleteDir(path);
    }

    private static void DeleteDir(string dir)
    {
        try
        {
            Thread.Sleep(1);
            Directory.Delete(dir, true);
        }
        catch (IOException)
        {
            DeleteDir(dir);
        }
        catch (UnauthorizedAccessException)
        {
            DeleteDir(dir);
        }
    }

2

এটির কি আপনার দৌড়ের অবস্থা রয়েছে যেখানে অন্য থ্রেড বা প্রক্রিয়া ডিরেক্টরিতে ফাইল যুক্ত করছে:

ক্রমটি হ'ল:

মুছে ফেলার প্রক্রিয়া এ:

  1. ডিরেক্টরি খালি করুন
  2. (এখন খালি) ডিরেক্টরি মুছুন।

যদি অন্য কেউ যদি 1 এবং 2 এর মধ্যে একটি ফাইল যুক্ত করে, তবে সম্ভবত 2 ব্যতিক্রম তালিকাভুক্ত করা হবে?


2

ডিরেক্টরিটি মোছার সাথে এই সমস্যাটি এবং অন্যান্য ব্যতিক্রমগুলি সমাধান করতে আমি কয়েক ঘন্টা ব্যয় করেছি। এটা আমার সমাধান

 public static void DeleteDirectory(string target_dir)
    {
        DeleteDirectoryFiles(target_dir);
        while (Directory.Exists(target_dir))
        {
            lock (_lock)
            {
                DeleteDirectoryDirs(target_dir);
            }
        }
    }

    private static void DeleteDirectoryDirs(string target_dir)
    {
        System.Threading.Thread.Sleep(100);

        if (Directory.Exists(target_dir))
        {

            string[] dirs = Directory.GetDirectories(target_dir);

            if (dirs.Length == 0)
                Directory.Delete(target_dir, false);
            else
                foreach (string dir in dirs)
                    DeleteDirectoryDirs(dir);
        }
    }

    private static void DeleteDirectoryFiles(string target_dir)
    {
        string[] files = Directory.GetFiles(target_dir);
        string[] dirs = Directory.GetDirectories(target_dir);

        foreach (string file in files)
        {
            File.SetAttributes(file, FileAttributes.Normal);
            File.Delete(file);
        }

        foreach (string dir in dirs)
        {
            DeleteDirectoryFiles(dir);
        }
    }

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


8
-1 দেরি কিসের কথা? কাকতালীয়ভাবে কোন প্রোগ্রামিং নেই দয়া করে!
রুবেন বারটেলিংক

1
@ রুবেন আমি বলিনি যে আপনি এটি সম্পর্কে ভুল। আমি কেবল বলেছি যে এটির জন্য এইটিকে নিম্নমান দেওয়া একটি কঠোর শাস্তি। আমি আপনার সাথে একমত হই, তবে, 4 টি upvotes 4 টি ডাউনভোটের ফলাফল দেয় নি। আমি আপনার মন্তব্যটিও উজ্জীবিত করব, তবে একটি অব্যক্ত দেরির কারণে আমি উত্তরটি হ্রাস করব না :)
থান্ডারগ্রি

1
@ রুবেনবার্টেলিংক এবং অন্যরা: যদিও আমি এই কোডটি বিশেষভাবে পছন্দ করি না (আমি একই ধরণের পদ্ধতির সাথে অন্য একটি সমাধান পোস্ট করেছি), এখানে বিলম্ব যুক্তিসঙ্গত। সমস্যাটি সম্ভবত অ্যাপের নিয়ন্ত্রণের বাইরে রয়েছে; সম্ভবত অন্য কোনও অ্যাপ অন্তত সময়ে FS পুনরুদ্ধার করে, এভাবে অল্প সময়ের জন্য ফোল্ডারটি লক করে। বিলম্বটি সমস্যার সমাধান করে, বাগ রিপোর্টটি শূন্যের নিচে পেয়ে যায়। মূল কারণ সম্পর্কে আমাদের যদি কোনও ফ্রিগিং ধারণা না থাকে তবে কে চিন্তা করে?
আন্দ্রে তারানসভ

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

1
@ রুবেনবার্টেলিংক আরেকটি প্রাক্তন, বলুন যে আপনি 100 মিমি বিলম্ব দিচ্ছেন, এবং লক্ষ্য পিসিতে কোনও সফ্টওয়্যারের সর্বোচ্চ লক টাইম হল এভি সফ্টওয়্যার = 90 মিমি। বলুন এটিতে ব্যাকআপ সফ্টওয়্যার রয়েছে যা 70 মিমি জন্য ফাইলগুলি লক করে। এখন এভি একটি ফাইল লক করে, আপনার অ্যাপ্লিকেশনটি 100 মিমি অপেক্ষা করে, যা সাধারণত সূক্ষ্ম হয়, তবে তার পরে অন্য একটি লকের মুখোমুখি হয় কারণ ব্যাকআপ সফ্টওয়্যারটি এভি স্ক্যানের 70ms চিহ্নে ফাইলটি ধরে নেওয়া শুরু করে এবং ফাইলটি ছেড়ে দিতে আরও 40 মিমি লাগবে। সুতরাং যখন এভি সফ্টওয়্যারটি আরও বেশি সময় নেয় এবং আপনার 100 মিমি 2 টি অ্যাপের যে কোনওটির চেয়ে সাধারণত লম্বা হয়, তবুও এটি মাঝখানে শুরু হওয়ার পরে আপনাকে অ্যাকাউন্ট করতে হবে।
vapcguy

2

পুনরাবৃত্ত ডিরেক্টরি মুছে ফেলা যা ফাইলগুলি মুছে না তা অবশ্যই অপ্রত্যাশিত। তার জন্য আমার স্থিরতা:

public class IOUtils
{
    public static void DeleteDirectory(string directory)
    {
        Directory.GetFiles(directory, "*", SearchOption.AllDirectories).ForEach(File.Delete);
        Directory.Delete(directory, true);
    }
}

আমি এটির ক্ষেত্রে অভিজ্ঞতা অর্জন করেছি, তবে সাধারণত, ডিরেক্টরি D ডিলিট এমএসডিএন-তে নথিভুক্ত হিসাবে পুনরাবৃত্তি মোছার পরে ডিরেক্টরিগুলির মধ্যে ফাইলগুলি মুছে দেয়

উইন্ডোজ এক্সপ্লোরারের ব্যবহারকারী হিসাবেও আমি সময়ে সময়ে এই অনিয়মিত আচরণটির মুখোমুখি হয়েছি: কখনও কখনও আমি কোনও ফোল্ডার মুছতে পারি না (এটি মনে হয় অযৌক্তিক বার্তাটি "অ্যাক্সেস অস্বীকৃত") তবে যখন আমি নীচে আইটেমগুলি ড্রিল করি এবং মুছতে পারি তখন আমি উপরেরটি মুছতে পারি আইটেম হিসাবে। সুতরাং আমি অনুমান করি যে উপরের কোডটি কোনও ওএসের বিপরীতে আচরণ করে - বেস ক্লাসের লাইব্রেরি ইস্যুর সাথে নয়।


1

এতে থাকা ডিরেক্টরি বা কোনও ফাইল লক করা আছে এবং মোছা যাবে না। যে অপরাধীকে এটি তালাবদ্ধ করেছে তা সন্ধান করুন এবং দেখুন আপনি এটি নির্মূল করতে পারেন কিনা।


টি -১০০০-সহ-ফোল্ডার-সহ ব্যবহারকারীকে: "আপনি সমাপ্ত!"
vapcguy

1

উইন্ডোজ এক্সপ্লোরারটিতে নির্বাচিত পাথ বা সাবফোল্ডারটি ডিরেক্টরী.ডিলিট (পথ, সত্য) এর একক এক্সিকিউশনটি ব্লক করার জন্য যথেষ্ট, উপরে বর্ণিত আইওএক্সেপশন নিক্ষেপ করা এবং উইন্ডোজ এক্সপ্লোরারকে প্যারেন্ট ফোল্ডারে আউট না করে মরার পরিবর্তে প্রক্রিয়াজাতকরণ করা যথেষ্ট প্রত্যাশিত।


এটি আমার সমস্যা হয়েছে বলে মনে হয়। যত তাড়াতাড়ি আমি এক্সপ্লোরার বন্ধ করে দিয়ে আবার দৌড়েছি, তার ব্যতিক্রম নেই। এমনকি পিতামাতার পিতামাতার নির্বাচন করাও যথেষ্ট ছিল না। আমাকে আসলে এক্সপ্লোরার বন্ধ করতে হয়েছিল।
স্কট মার্লো

হ্যাঁ, এটি ঘটে এবং এটি একটি কারণ। সুতরাং প্রোগ্রামিয়ালি কীভাবে এটি মোকাবেলা করতে হয় তার কোনও ধারণা, বা উত্তরটি সবসময়ই নিশ্চিত করা যায় যে সমস্ত 1000 ব্যবহারকারী এই ফোল্ডারটি বন্ধ আছে?
ভ্যাপকুই

1

আমার আজ এই সমস্যা ছিল। এটি ঘটছিল কারণ আমার কাছে উইন্ডোজ এক্সপ্লোরার যে ডিরেক্টরিটি মুছে ফেলার চেষ্টা করেছিল তার জন্য খোলা ছিল, যার ফলে পুনরাবৃত্তির কলটি ব্যর্থ হয়েছিল এবং এইভাবে IOException। ডিরেক্টরিতে কোনও হ্যান্ডেল খোলা নেই তা নিশ্চিত করুন।

এছাড়াও, এমএসডিএন স্পষ্ট যে আপনার নিজের পুনর্বিবেচনাটি লিখতে হবে না: http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx


1

উইন্ডোজ ওয়ার্কফ্লো ফাউন্ডেশনে টিএফএস ২০১২ সহ একটি বিল্ড সার্ভারে আমার একই সমস্যা ছিল। অভ্যন্তরীণভাবে, কার্যপ্রবাহ ডাইরেক্টরি বলে ডিলিট (ডিলিট) নামে পুনরাবৃত্ত পতাকাটি সত্য হিসাবে সেট করে। এটি আমাদের ক্ষেত্রে নেটওয়ার্ক সম্পর্কিত বলে মনে হচ্ছে।

আমরা সর্বশেষতম বাইনারিগুলির সাথে পুনরায় তৈরি এবং পুনঃ-জনসংখ্যার পূর্বে একটি নেটওয়ার্ক শেয়ারে বাইনারি ড্রপ ফোল্ডারটি মুছছিলাম। অন্য প্রতিটি বিল্ড ব্যর্থ হবে। ব্যর্থ বিল্ডের পরে ড্রপ ফোল্ডারটি খোলার সময়, ফোল্ডারটি খালি ছিল যা নির্দেশ করে যে ডাইরেক্টরি.ডিলিট () কলটির প্রতিটি দিকই প্রকৃত ডিরেক্টরি মুছে ফেলা ব্যতীত সফল হয়েছিল।

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

আমাদের ক্ষেত্রে দুটি সম্ভাব্য সমাধান:

  • প্রতিটি পদক্ষেপের মধ্যে বিলম্ব এবং যাচাইকরণের সাথে আমাদের নিজস্ব কোডে পুনরাবৃত্ত মোছা তৈরি করুন
  • IOException এর পরে X বার চেষ্টা করুন, আবার চেষ্টা করার আগে বিলম্ব করুন giving

পরবর্তী পদ্ধতিটি দ্রুত এবং নোংরা তবে কৌশলটি মনে হচ্ছে।


1

এটি ফাইলচেনজ নোটফিকেশনগুলির কারণে

এটি এএসপি.নেট ২.০.২০১। সাল থেকে ঘটে। আপনি যখন কোনও অ্যাপ্লিকেশনের মধ্যে কিছু ফোল্ডার মুছবেন তখন তা পুনরায় শুরু হবে । আপনি এটি দেখতে পারেন, এএসপি.এনইটি স্বাস্থ্য পর্যবেক্ষণ ব্যবহার করে

এই কোডটি কেবল আপনার ওয়েলকনফিগ / কনফিগারেশন / সিস্টেমে যুক্ত করুন। ওয়েবে:

<healthMonitoring enabled="true">
  <rules>
    <add name="MyAppLogEvents" eventName="Application Lifetime Events" provider="EventLogProvider" profile="Critical"/>
  </rules>
</healthMonitoring>


তার পরে চেক আউট Windows Log -> Application। কি হচ্ছে:

আপনি যখন ফোল্ডারটি মুছবেন, যদি কোনও Delete(path, true)সাব-ফোল্ডার থাকে তবে প্রথমে সাব-ফোল্ডারটি মুছুন । ফাইল অ্যাপ্লিকেশন মনিটরের পক্ষে আপনার অ্যাপ্লিকেশনটি অপসারণ এবং বন্ধ করার বিষয়ে জানতে যথেষ্ট enough এদিকে আপনার মূল ডিরেক্টরিটি এখনও মুছে ফেলা হয়নি। এটি লগ থেকে ইভেন্ট:


এখানে চিত্র বর্ণনা লিখুন


Delete() এর কাজ শেষ করেনি এবং অ্যাপ্লিকেশনটি বন্ধ হয়ে যাওয়ায় এটি একটি ব্যতিক্রম উত্থাপন করে:

এখানে চিত্র বর্ণনা লিখুন

আপনি যে ফোল্ডারটি মুছে ফেলছেন সেটিতে আপনার কোনও সাবফোল্ডার নেই , মুছে ফেলুন () সবেমাত্র সমস্ত ফাইল এবং সেই ফোল্ডারটি মুছুন, অ্যাপটিও আবার চালু হচ্ছে, তবে আপনি কোনও ব্যতিক্রম পাবেন না , কারণ অ্যাপ্লিকেশন পুনঃসূচনা কোনও বাধা দেয় না। তবে তবুও, আপনি সমস্ত ইন-প্রসেস সেশন হারাবেন, অ্যাপ্লিকেশন পুনরায় আরম্ভ করার সময় অনুরোধগুলির প্রতিক্রিয়া জানায় না, ইত্যাদি etc.

এখন কি?

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

  1. এমন একটি নিয়ামক তৈরি করুন যা আগত কলগুলি পরিচালনা করে এবং তারপরে কোনও অ্যাপের বাইরে (wwwroot এর বাইরে) ফোল্ডারটি পড়ে ফাইলগুলি পরিবেশন করে।

  2. যদি আপনার প্রকল্পটি বড় হয় এবং পারফরম্যান্স সবচেয়ে গুরুত্বপূর্ণ হয়, স্থির বিষয়বস্তু পরিবেশন করার জন্য পৃথক ছোট এবং দ্রুত ওয়েবসার্ভার সেট আপ করুন। এভাবে আপনি তাঁর নির্দিষ্ট কাজ আইআইএস-এ চলে যাবেন। এটি একই মেশিনে থাকতে পারে (উইন্ডোজের জন্য মঙ্গুজ) বা অন্য কোনও মেশিনে (লিনাক্সের জন্য এনগিনেক্স)। সুসংবাদটি হ'ল লিনাক্সে স্থিতিশীল কন্টেন্ট সার্ভার স্থাপন করতে আপনাকে অতিরিক্ত মাইক্রোসফ্ট লাইসেন্স দিতে হবে না।

আশাকরি এটা সাহায্য করবে.


1

উপরে উল্লিখিত হিসাবে "গৃহীত" সমাধানটি পুনর্বার পয়েন্টগুলিতে ব্যর্থ হয় - তবুও লোকেরা এখনও এটি চিহ্নিত করে (???)। একটি আরও সংক্ষিপ্ত সমাধান রয়েছে যা কার্যকারিতাটির যথাযথভাবে প্রতিস্থাপন করে:

public static void rmdir(string target, bool recursive)
{
    string tfilename = Path.GetDirectoryName(target) +
        (target.Contains(Path.DirectorySeparatorChar.ToString()) ? Path.DirectorySeparatorChar.ToString() : string.Empty) +
        Path.GetRandomFileName();
    Directory.Move(target, tfilename);
    Directory.Delete(tfilename, recursive);
}

আমি জানি, পরে উল্লিখিত অনুমতিগুলির কেসগুলি পরিচালনা করে না, তবে সমস্ত অভিপ্রায় এবং উদ্দেশ্যগুলির জন্য এয়ার বেটার মূল / স্টক ডিরেক্টরিটির প্রত্যাশিত কার্যকারিতা সরবরাহ করে e ডিলিট () - এবং অনেক কম কোড সহও

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

সুবিধা হিসাবে, আপনি যদি জানেন যে আপনার টার্গেট ডিরেক্টরিটি বড় / গভীর এবং অপেক্ষা করতে চান না (বা ব্যতিক্রম নিয়ে বিরক্ত করুন) তবে শেষ লাইনটি প্রতিস্থাপন করা যেতে পারে:

    ThreadPool.QueueUserWorkItem((o) => { Directory.Delete(tfilename, recursive); });

আপনি এখনও কাজ চালিয়ে যাওয়া নিরাপদ।


2
আপনার অ্যাসাইনমেন্টটি কী সহজ করা যাবে: স্ট্রিং tfilename = Path.Combine (Path.GetDirectoryName (লক্ষ্য), Path.GetRandomFileName ());
পিট

1
পিট এর সাথে আমার একমত হতে হবে লিখিত হিসাবে কোড বিভাজক যোগ করবে না। এটি আমার পথে নিয়েছে \\server\C$\dirএবং এটি তৈরি করেছে \\server\C$asf.yuw। ফলস্বরূপ আমি এতে একটি ত্রুটি পেয়েছি Directory.Move()- Source and destination path must have identical roots. Move will not work across volumes. একবার আমি পিট কোড এক্সেসিপিটি ব্যবহার করলে জরিমানা ঠিক হয় না যখন লক করা ফাইল বা খোলা ডিরেক্টরি থাকে তা হ্যান্ডেল করে না - সুতরাং এটি কখনই ThreadPoolকমান্ডটি পায় না ।
vapcguy

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

1

এই সমস্যাটি উইন্ডোজে উপস্থিত হতে পারে যখন কোনও ডিরেক্টরিতে (বা কোনও উপ-ডিরেক্টরিতে) ফাইল থাকে যেখানে পাথের দৈর্ঘ্য 260 চিহ্নের চেয়ে বেশি।

এই জাতীয় ক্ষেত্রে এর \\\\?\C:\mydirপরিবর্তে আপনার মুছতে হবে C:\mydir। 260 টি প্রতীক সীমা সম্পর্কে আপনি এখানে পড়তে পারেন ।


1

আমি এই সহস্রাব্দ কৌশলটি সমাধান করেছি (আপনি থ্রেডটি ছেড়ে দিতে পারেন the ক্যাচে তার নিজের উপর ঘুমান)

bool deleted = false;
        do
        {
            try
            {
                Directory.Delete(rutaFinal, true);                    
                deleted = true;
            }
            catch (Exception e)
            {
                string mensaje = e.Message;
                if( mensaje == "The directory is not empty.")
                Thread.Sleep(50);
            }
        } while (deleted == false);

0

আপনার অ্যাপ্লিকেশনটির (বা অন্য কোনও অ্যাপ্লিকেশনটির) বর্তমান ডিরেক্টরি যদি আপনি মুছে ফেলার চেষ্টা করছেন তবে এটি কোনও অ্যাক্সেস লঙ্ঘন ত্রুটি হবে না তবে কোনও ডিরেক্টরি খালি নয়। বর্তমান ডিরেক্টরিটি পরিবর্তন করে নিশ্চিত করুন যে এটি আপনার নিজস্ব প্রয়োগ নয়; এছাড়াও, নিশ্চিত হয়ে নিন যে ডিরেক্টরিটি অন্য কোনও প্রোগ্রামে খোলা নেই (যেমন ওয়ার্ড, এক্সেল, মোট কমান্ডার, ইত্যাদি)। বেশিরভাগ প্রোগ্রামগুলি শেষ ফাইলটি খোলার ডিরেক্টরিতে সিডি করবে, যার কারণ হবে।


0

নেটওয়ার্ক ফাইলগুলির ক্ষেত্রে ডিরেক্টরি ডিলিটহেল্পার (পুনরাবৃত্ত: = সত্য) আইওএক্সেপশন হতে পারে যা ফাইল মোছার বিলম্বের কারণে ঘটেছিল


0

আমি মনে করি যে কিছু স্ট্রিমের মাধ্যমে একটি ফাইল খোলা আছে যা আপনি জানেন না আমার একই সমস্যা ছিল এবং আমি যে ডিরেক্টরিটি মুছতে চাইছি সেখানে নির্দেশ করে এমন সমস্ত স্ট্রিম বন্ধ করে সমাধান করেছি।


0

কোনও ফাইল বা ডিরেক্টরি ব্যবহারের জন্য বিবেচিত হলে এই ত্রুটি ঘটে occurs এটি একটি বিভ্রান্তিকর ত্রুটি। আপনার গাছের যে কোনও ডিরেক্টরিতে কোনও এক্সপ্লোরার উইন্ডো বা কমান্ড-লাইন উইন্ডোজ খোলা আছে কিনা তা পরীক্ষা করে দেখুন বা সেই প্রোগ্রামটিতে যে প্রোগ্রামটি সেই গাছের কোনও ফাইল ব্যবহার করছে।


0

পদ্ধতিগুলি যখন এ্যাসএনসিড হয় এবং কোড কোড করা হয় তখন আমি বর্ণিত সমস্যার সম্ভাব্য উদাহরণটি সমাধান করেছি:

// delete any existing update content folder for this update
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
       await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

এর সাথে:

bool exists = false;                
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
    exists = true;

// delete any existing update content folder for this update
if (exists)
    await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

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


0

পুনরাবৃত্তির জন্য আপনার তৈরি এবং অতিরিক্ত পদ্ধতি বা ফোল্ডারের অতিরিক্ত ফাইলগুলি মুছতে হবে না। এই সব কল করে স্বয়ংক্রিয়ভাবে করছে

DirectoryInfo.Delete ();

বিশদ এখানে

এর মতো কিছু বেশ ভাল কাজ করে:

  var directoryInfo = new DirectoryInfo("My directory path");
    // Delete all files from app data directory.

    foreach (var subDirectory in directoryInfo.GetDirectories())
    {
          subDirectory.Delete(true);// true set recursive paramter, when it is true delete sub file and sub folder with files too
    }

পদ্ধতি মোছার জন্য ভেরিয়েবল হিসাবে সত্য পাস করা, ফাইল সহ সাব ফাইল এবং সাব ফোল্ডারটি মুছে ফেলবে।


-2

উপরের উত্তরগুলির কোনওটিই আমার পক্ষে কার্যকর হয়নি। এটি মনে হয় যে DirectoryInfoটার্গেট ডিরেক্টরিতে আমার নিজের অ্যাপ্লিকেশনটির ব্যবহারের ফলে এটি লক থাকার কারণে ঘটছে।

জঞ্জাল সংগ্রহের জন্য জোর করে সমস্যাটি সমাধান করার জন্য উপস্থিত হয়েছিল, তবে এখনই তা নয়। যেখানে প্রয়োজন মুছে ফেলার কয়েকটি প্রচেষ্টা।

Directory.Existsএটি ব্যতিক্রম পরে অদৃশ্য হয়ে যেতে পারে হিসাবে নোট করুন । আমি জানি না কেন আমার জন্য মুছতে বিলম্ব হয়েছিল (উইন্ডোজ 7 এসপি 1)

        for (int attempts = 0; attempts < 10; attempts++)
        {
            try
            {
                if (Directory.Exists(folder))
                {
                    Directory.Delete(folder, true);
                }
                return;
            }
            catch (IOException e)
            {
                GC.Collect();
                Thread.Sleep(1000);
            }
        }

        throw new Exception("Failed to remove folder.");

1
কাকতালীয়ভাবে প্রোগ্রামিং। GC'd হলে কোন বস্তুটি কী করবে? এটি কি কোনও উপায়ে ভাল সাধারণ পরামর্শ? (আমি আপনাকে বিশ্বাস করি যখন আপনি বলেন যে আপনার কোনও সমস্যা হয়েছে এবং আপনি এই কোডটি ব্যবহার করেছেন এবং আপনার মনে হয় যে আপনার এখন কোনও সমস্যা নেই তবে এটি কেবল বিন্দু নয়)
রুবেন বারটেলিংক

@ রুবেনবার্টেলিংক আমি সম্মত। এটি একটি হ্যাক। ভুডো কোড যা এমন কিছু করে যখন এটি কী সমাধান করছে বা কীভাবে তা পরিষ্কার নয়। আমি একটি সঠিক সমাধান চাই।
প্রতিক্রিয়া

1
আমার সমস্যাটি হ'ল এটি স্ট্যাকওভারফ্লো . com/a/14933880/11635 এর উপরে এবং উপরে যে কোনও কিছু যুক্ত করে তা অত্যন্ত অনুমানমূলক। যদি আমি পারতাম তবে আমি সদৃশ দ্বারা নকলকরণের জন্য একটি -1 এবং কৌতূহল দ্বারা অনুমান / প্রোগ্রামিংয়ের জন্য একটি -1 দিচ্ছি। ছিটিয়ে দেওয়া GC.Collect) ক) খারাপ পরামর্শ এবং খ) লকড ডায়ারের যথেষ্ট সাধারণ সাধারণ কারণ এখানে মেধা অন্তর্ভুক্তির যোগ্য নয়। কেবল অন্য একজনকে বেছে নিন এবং নিরীহ পাঠকদের মনে আরও বিভ্রান্তি বোধ করবেন না
রুবেন বার্টালিংক

3
জিসি.ওয়েটফরপেন্ডিংফাইনালাইজারগুলি () ব্যবহার করুন; জিসি.কালেক্ট () পরে; এটি প্রত্যাশার মতো কাজ করবে।
হেইনার

না নিশ্চিত, অপরীক্ষিত, কিন্তু সম্ভবত ভাল একটি সঙ্গে কিছু করতে হবে usingতাহলে বিবৃতি using (DirectoryInfo di = new DirectoryInfo(@"c:\MyDir")) { for (int attempts = 0; attempts < 10; attempts++) { try { if (di.Exists(folder)) { Directory.Delete(folder, true); } return; } catch (IOException e) { Thread.Sleep(1000); } } }
vapcguy

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