System.IO.IOException: System.IO.Path.GetTempFileName () - রেজোলিউশন ব্যবহার করার সময় "ফাইলটি বিদ্যমান"?


86

যখনই তিনি আমার পণ্যটি ব্যবহার করার চেষ্টা করেছিলেন তখন আমার একজন গ্রাহক ব্যতিক্রম পেয়েছিলেন। আমি যে ব্যতিক্রম ঘটেছে তার কলস্ট্যাকটি পেয়েছি, যার শীর্ষটি হল:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.__Error.WinIOError()
   at System.IO.Path.GetTempFileName()
   at System.Windows.Input.Cursor.LoadFromStream(Stream cursorStream)
   at System.Windows.Input.Cursor..ctor(Stream cursorStream)

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

আমি% TEMP% ফোল্ডারটিকে প্রোগ্রামগতভাবে পরিষ্কার করতে পারছি না, কারণ এটি অন্যরকম কিছু ক্ষতি করতে পারে এবং আমি getTempFileName (এবং তার পরিবর্তে আমার নিজের টেম্প ফোল্ডারটি ব্যবহার করা) এড়াতে পারি না কারণ এটি আমার নয় তবে ডাব্লুপিএফ কোড যা এটি কল করছে।

এর কোন স্থায়ী সমাধান আছে কি?

আপডেট : আমি নিশ্চিত করেছি যে% TEMP% ফোল্ডারটি লগ ফাইলগুলিতে উপচে পড়ছে সে সমস্যাটি আমার নিজের কোড দ্বারা সৃষ্ট নয় এবং এটি গ্রাহকের মেশিনে অন্য কোনও তৃতীয় পক্ষের অ্যাপ্লিকেশন দ্বারা সৃষ্ট হতে হবে। আমি এর বাস্তবায়নও দেখেছি Cursor.LoadFromStreamএবং এটি অবশ্যই দোষের নয় - এটি একটি অস্থায়ী ফাইল তৈরি করে, তবে এটি finallyব্লকে মুছে দেয় ।


4
আপনি নিজের "টেম্প" ফোল্ডারটি তৈরি করতে পারেন যা মুছে ফেলা হয় (অ্যাপ্লিকেশন ডেটাতে) তবে সম্ভবত সমস্ত তথ্যসূত্র পরিবর্তন করার জন্য এটি একটি ব্যাল্যাচে হতে পারে, ভাল প্রশ্ন
— ই

প্রশ্নটি ডাব্লুপিএফ সম্পর্কিত নয়, সরানো ট্যাগ। এছাড়াও, কেন কেবল কোডটি স্থির করবেন না, যা মোছা ছাড়াই এতগুলি অস্থায়ী ফাইল তৈরি করে?
— ডেনিস

4
@ সেয়েস আমি এটি করতে পারছি না কারণ এটি ডাব্লুপিএফ এরাই Cursor.LoadFromStreamটেম্প ফাইল তৈরি করে। @ ডেনিস এটি ডাব্লুপিএফ-এর Cursor.LoadFromStreamশ্রেণীর সাথে সম্পর্কিত । আপত্তিজনক কোড যা মুছে ফেলা ছাড়াই এতগুলি অস্থায়ী ফাইল তৈরি করে তা আমার নিজেরও নাও হতে পারে এবং আমার এখনও এর ব্যতিক্রমটি সম্বোধন করতে হবে।
— ওমর রাভিভ

এই অ্যাপ্লিকেশনটি সমস্ত টেম্প ফাইলের পিছনে কোন অ্যাপ্লিকেশনটি রেখে যাচ্ছে তা আপনি জানতে পারবেন? এটা কি আপনার আবেদন? যদি ডাব্লুপিএফ নিজেই এই টেম্প ফাইলগুলি তৈরি করে থাকে তবে আপনি কি নিশ্চিত হয়ে গেছেন যে এগুলি আর প্রয়োজন হয় না সেগুলি মুছে ফেলছে?
— আশিগোর

4
@ ওমররভিভ আমি মনে করি তারপরে আপনার একমাত্র বিকল্প হ'ল আইওই চেষ্টা করা / ধরা এবং ব্যবহারকারীরা যদি আপনাকে টেম্প ফাইলগুলি মুছতে চান এবং পুনরায় চেষ্টা করতে চান
— 7135 এ সায়স

উত্তর:


16

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

public Stream GetStream(Stream cursorStream)
{
    try
    {
       //getting stream
    }
    catch(IOE)
    {
        MessageBox.Show(this, "Unable to get stream, your temporary
                              folder may be full, do you want to try deleting 
                                some and try again?");
         if(yes)
         try
         {
             //delete and try again
             return GetStream(cursorStream);
         }
         catch(IOE)
          {
                //no luck
           }
          else
              return null;
    }

}

এটি হতে পারে তা নিশ্চিত করার জন্য একটি alচ্ছিক চেক,

Directory.EnumerateFiles(Path.GetTempPath(), "*", SearchOption.TopLevelOnly)
  .Count() == ushort.MaxValue;

4
আপনার পরামর্শ অনুসারে আমি চেষ্টা করে যাচ্ছি catch আপনার প্রস্তাবিত বুলিয়ান পরীক্ষাটি আসলে ভুল - সম্ভবত "টিএমপিএক্সএক্সএক্সএক্সএক্সপি" ফর্ম্যাটে যেগুলি গেটেম্পফিলনাম () ব্যবহার করে সেগুলি ছাড়াও অন্যান্য ফাইলগুলি সম্ভবত রয়েছে, সুতরাং আপনার সমস্যাটি সত্যই ফিরে আসতে পারে যখন আসলেই কোনও সমস্যা নেই এবং মিথ্যা যখন কোন সমস্যা আছে।
— ওমর রাভিভ

পরীক্ষার জন্য একটি টেম্প ফোল্ডারে সমস্ত ফাইল সন্ধান করার জন্য ডিজাইন করা হয়েছিল (যদিও আমি স্বীকার করি এটি সঠিক টেম্প ফোল্ডারটি নাও হতে পারে) এবং "*"এটি যদি 65535 এর সমান হয় তবে সমস্ত ফাইল সন্ধান করবে (তাদের এক্সটেনশন রয়েছে বা না থাকুক) আশা করি এটি সাহায্য করে
— ই

আপনি একদিনের চেয়ে বেশি পুরানো সমস্ত ফাইল মুছতে পারবেন। এক দিনের চেয়ে পুরানো একটি অস্থায়ী ফাইল অন্য কোনও অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হওয়ার সম্ভাবনা নেই।
— জেটি টেলর

4
Alচ্ছিক চেকের আরও একটি পয়েন্ট। আমি যখন একটি বিল্ড সার্ভারে এই সমস্যাটি ছড়িয়েছি তখন অস্থায়ী ডিরেক্টরিতে 65535 এরও বেশি ফাইল ছিল। এই গণনাটি কেবল তখনই কাজ করে যদি কেবলমাত্র অস্থায়ী ফাইল তৈরির জিনিসটি পথ সহায়ক শ্রেণীর মাধ্যমে হয়।
— রশ্মদমান

37

এটি যদি আপনার সাথে ঘটে থাকে উত্পাদনের পরিবেশে বা এমন কোনও অ্যাপের সাথে যা আপনি পরিবর্তন করতে পারবেন না, দ্রুত সমাধান হ'ল টেম্প ফোল্ডারটি খালি করা।

যে অ্যাপ্লিকেশনটি চালাচ্ছেন তার উপর নির্ভর করে আপনারও উচিত either

  • খালি C:\Windows\Temp (আইআইএস বা LocalSystemঅ্যাকাউন্টের অধীনে চলমান পরিষেবার জন্য )
  • অথবা %temp%স্থানীয়ভাবে ব্যবহারকারীদের জন্য লগইন করা হয়েছে (যা আমার পক্ষেC:\Users\MyUserName\AppData\Local\Temp )।

অন্যদিকে, যদি আপনার নিজস্ব কোড এটি ছুঁড়ে মারছে, এবং আপনি এটিকে আবার কখনও ঘটতে বাধা দিতে চান:

  1. System.IO.Path.GetTempFileName () ব্যবহার করবেন না!

GetTempFileName()দুই দশকের পুরানো উইন 32 এপি'র একটি মোড়ক । এটি ফাইলের নাম তৈরি করে যা খুব সহজেই সংঘর্ষে পরিণত হয়। এটি ফাইল সিস্টেমের উপর ভারীভাবে লুপিং করে, সম্ভাব্য ফাইলের নামগুলি পুনরাবৃত্তি করে এই সংঘর্ষগুলির সমাধান করে"%temp%\tmp0000.tmp" করা "tmpFFFF.tmp"এবং ইতিমধ্যে বিদ্যমান বিদ্যমানগুলি এড়িয়ে । এটি একটি I / O নিবিড়, ধীর এবং স্পষ্টতই ভয়ানক অ্যালগরিদম। ব্যর্থ হওয়ার আগে কেবলমাত্র 4 টি হেক্স অক্ষর ব্যবহার হ'ল 65536 ফাইলের কৃত্রিম সীমা তৈরি করে।

বিকল্পটি হ'ল ফাইলের নাম উত্পন্ন করা যা সংঘর্ষে পড়বে না। উদাহরণস্বরূপ, GUID'sযুক্তি পুনরায় ব্যবহার করতে দিন : 32 হেক্স সংখ্যা প্রায় কখনও সংঘর্ষে পড়বে না।

private string GetTempFileName()
{
    return Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
}
// Sample: c:\Windows\Temp\2e38fe87-f6bb-4b0d-90b3-2d07016324c1

এটি 65k থেকে 4k মিলিয়ন ফাইল সর্বাধিক (তাত্ত্বিকভাবে) সীমা প্রসারিত করে ... অবশ্যই, 65k ফাইলগুলি ফাঁস করা ইতিমধ্যে ভয়ানক, তাই ...

  1. টেম্পল ফাইল ফাঁস করবেন না!

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

  1. টেম্প ফোল্ডারটি পরিষ্কার করুন

এখনই এটি পরিষ্কার করুন এবং পর্যায়ক্রমে এটি পরিষ্কার করতে সিস্টেম প্রশাসককে শিক্ষিত করুন, কারণ আপনি বন্যের প্রতিটি অ্যাপ্লিকেশনকে বিশ্বাস করতে পারবেন না। আমার নিজের সার্ভারগুলিতে আমি এই কাজটি ব্যবহার করে স্বয়ংক্রিয় করব:

  • গ্লোবাল উইন্ডোজ \ টেম্পের জন্য

schtasks /Create /TR "cmd /c call DEL /F /S /Q %^TEMP%" /TN "Delete Global Temp Files" /sc WEEKLY /ST 12:00 /ru system

  • বর্তমান ব্যবহারকারীর জন্য:

schtasks /Create /TR "cmd /c call DEL /F /S /Q %^TEMP%" /TN "Delete %username% Temp Files" /sc WEEKLY /ST 12:00


5

এখানে আমি কোডটি শেষ পর্যন্ত ব্যবহার করেছি এবং আমার অ্যাপ্লিকেশনটির প্রারম্ভিককরণ কোড-পাথের শুরুতে রেখেছি, কোনও কল আসতে Cursor.LoadFromStreamপারে তার আগে :

    private void WarnUserIfTempFolderFull()
    {
        string tempFile = null;
        try
        {
            tempFile = Path.GetTempFileName();
        }
        catch (IOException e)
        {
            string problem = "The Temporary Folder is full.";

            string message = "{ProductName} has detected that the Windows Temporary Folder is full. \n" + 
                             "This may prevent the {ProductName} from functioning correctly.\n" + 
                             "Please delete old files in your temporary folder (%TEMP%) and try again.";

            Logger.Warn(problem);

            MessageBox.Show(message, caption: problem);
        }
        finally
        {
            if (tempFile != null) File.Delete(tempFile);
        }
    }

2

সমাধান:

  1. সঠিক. কোন অ্যাপ্লিকেশন এতগুলি অস্থায়ী ফাইল তৈরি করছে এবং সেগুলি মোছছে না তা সনাক্ত করুন। মত Process monitorউপযোগ আপনি সাহায্য করা উচিত। তারপরে হয় অ্যাপ্লিকেশনটি ঠিক করুন বা এটিকে ফেলে দিন। এবং হ্যাঁ, এটি আপনার আবেদন হতে পারে। এজন্য আমি আপনাকে মন্দের উত্স সনাক্ত করার পরামর্শ দিই।
  2. সবচেয়ে সহজ। আপনার নিজের অস্থায়ী ডিরেক্টরি ব্যবহার করুন। আপনার কোড থেকে ফাইলগুলি তৈরি করা হচ্ছে এটি সাহায্য করবে না।
  3. কুৎসিত এক। আপনার অ্যাপ্লিকেশন থেকে অস্থায়ী ডিরেক্টরি সাফ করুন। আপনি পরিণতি সম্পর্কে একেবারে সঠিক - আপনি অন্য অ্যাপ্লিকেশনটি ভেঙে ফেলতে পারেন।

আপনার নিজের টেম্প ডিরেক্টরিটি অগত্যা কোনও সমাধান নয়। আমি একটি টেম্পাইল ফাইল তৈরি করতে এপিআই ব্যবহার করি তবে এটি নিজের ডিরেক্টরিতে লিখি। দুর্ভাগ্যক্রমে এমনকি ব্যর্থ।
— জর্জ মাউয়ার

2
// one more implementation
string GetTempFileName()
{
    return Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
}

1

হিসাবে Sayse প্রস্তাব, আপনি% TEMP% এনভায়রনমেন্ট ভেরিয়েবল সেট যখন আপনার অ্যাপ্লিকেশন লঞ্চ চেষ্টা করতে পারে।

Environment.SetEnvironmentVariable("TEMP", "<dir>");

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

এই সমাধানটি যদি তার নিজস্ব প্রোগ্রাম যা এই সমস্ত ফাইলকে পিছনে ফেলেছে তা সাহায্য করবে না। নতুন ডিরেক্টরিটি কেবল পূরণ করবে এবং কোনও ফোল্ডার থেকে নির্বিচারে ফাইলগুলি মুছে ফেলা খারাপ when
— আশিগোর

@ অশিগোর হ্যাঁ, স্পষ্টতই এটি তার তৈরি বাগটি ঠিক করবে না। বিশেষভাবে রেফারেন্সিং what if they are regularly running some other piece of software that makes frequent calls to GetTempFileName।
— এড চ্যাপেল

@ ওমররাভিভ এই তথ্যটি সহায়ক। প্রকৃতপক্ষে এটি এই পরিস্থিতিতে কাজ করবে না।
— এড চ্যাপেল

4
দুঃখিত @ এডচ্যাপেল, এসও আমার ভোট লক করেছে, উত্তর সম্পাদনা না করা পর্যন্ত আমি এটিকে সরাতে পারব না।
— জেরার্ডো গ্রিগনিওলি

1

অন্য কারও জন্য যারা এই সমস্যাটি দেখেছেন এবং কোনও উপচে পড়া টেম্প-ফোল্ডারটি খুঁজে পেতে পারেন না - "সি: / উইন্ডোজ / টেম্প" ফোল্ডারটি পরীক্ষা করুন। এই ফোল্ডারটি পরিষ্কার করা আমার সমস্যার সমাধান করেছে।

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