স্ট্রিমডারার নিষ্পত্তি করার ফলে কী প্রবাহ বন্ধ হয়ে যায়?


166

আমি লেখার জন্য পদ্ধতিগুলিতে একটি স্ট্রিম প্রেরণ করছি এবং সেই পদ্ধতিগুলিতে আমি বাইনারি পাঠক / কব্জি ব্যবহার করছি। পাঠক / লেখক যখন নিষ্পত্তি হয়ে যান, হয় usingবা কেবল যখন উল্লেখ করা হয় না, তখনও সেই ধারাটি কি বন্ধ হয়ে যায় ??

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

উত্তর:


204

হ্যাঁ, StreamReader, StreamWriter, BinaryReaderএবং BinaryWriterসব ঘনিষ্ঠ / তাদের অন্তর্নিহিত স্ট্রিম নিষ্পত্তি আপনি কল যখন Disposeতাদের উপর। পাঠক / লেখক যদি কেবল আবর্জনা সংগ্রহ করেন তবে তারা স্ট্রিমটি নিষ্পত্তি করে না - আপনার উচিত সবসময় পাঠক / লেখকের নিষ্পত্তি করা, পছন্দনীয় কোনও usingবিবৃতি দিয়ে। (প্রকৃতপক্ষে, এই শ্রেণীর কোনওটিরই চূড়ান্তকরণ নেই, তাদেরও হওয়া উচিত নয়))

ব্যক্তিগতভাবে আমি পাশাপাশি স্ট্রিমের জন্য একটি ব্যবহারের বিবৃতি দেওয়া পছন্দ করি। আপনি usingবেশ ঝরঝরে ধনুর্বন্ধনী ছাড়াই বাসা বাঁধতে পারেন:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

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


2
ওহ ভাল, ডিসপোজ কল করার সময়ই এটি ঘটে, অনুমিতভাবে চূড়ান্ত করার সময় নয়।
নেফজেন

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

13
এই নেস্টিংয়ের কারণে ভিএস কোড বিশ্লেষক অভিযোগ করে: CA2202 : Microsoft.Usage : Object 'stream' can be disposed more than once in method '...'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.এটি কি কেবল এড়ানো উচিত? আমি এখনও পর্যন্ত কোনও ব্যতিক্রম পাইনি ...
এইচবি

15
@ এইচবি: এই ক্ষেত্রে এটি এড়ানো নিরাপদ। অথবা আপনি কেবল কনস্ট্রাক্টরকে কল করতে স্ট্রিম তৈরি করতে পারেন StreamReader। এই সতর্কতাটি আমার কাছে বগাস বলে মনে হচ্ছে, প্রদত্ত ডকস IDisposable.Disposeস্পষ্টভাবে জানিয়েছে: "যদি কোনও বস্তুর ডিসপোজ পদ্ধতিটি একাধিকবার বলা হয় তবে অবজেক্টটিকে অবশ্যই প্রথম কলটির পরে সমস্ত কল উপেক্ষা করতে হবে The একাধিকবার বলা হয়। "
জন স্কিটি

5
@ জোনস্কিট: আসলে এর জন্য একটি পৃষ্ঠা রয়েছে , আপনি সঠিক ছিলেন, এটি বোগাস :)
এইচবি

45

এটি একটি পুরানো, তবে আমি আজ একই জাতীয় কিছু করতে চেয়েছি এবং দেখতে পেয়েছি যে জিনিসগুলি পরিবর্তিত হয়েছে। .NET 4.5 থেকে একটি leaveOpenযুক্তি রয়েছে:

public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )

একমাত্র সমস্যাটি হ'ল অন্যান্য পরামিতিগুলির জন্য কী সেট করতে হবে তা সম্পূর্ণ স্পষ্ট নয়। এখানে কিছু সহায়তা দেওয়া হল:

স্ট্রিমরিডার কনস্ট্রাক্টরের (স্ট্রিম) জন্য এমএসডিএন পৃষ্ঠা থেকে :

এই কনস্ট্রাক্টরটি ইউটিএফ 8 এনকোডিং, স্ট্রিম প্যারামিটার ব্যবহার করে বেসস্ট্রিম সম্পত্তি এবং অভ্যন্তরীণ বাফার আকারটি 1024 বাইটে এনকোডিং সূচনা করে।

এটি ঠিক ছেড়ে দেয় detectEncodingFromByteOrderMarksযা উত্স কোড দ্বারা বিচার করা হয়true

public StreamReader(Stream stream)
        : this(stream, true) {
}

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
        : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}

এই ডিফল্টগুলির মধ্যে কিছু প্রকাশিত হলে বা আর্গুমেন্টগুলি alচ্ছিক হলে আমরা কেবল যেগুলি চাই তা নির্দিষ্ট করতে পারি It


খুব সুন্দর তথ্য! এই নতুন প্যারামিটারটি কখনও শুনেনি এবং এটি আসলে অনেক অর্থবোধ করে।
জুলাইলগন

3
আমার মতো অলস লোকের জন্য, স্ট্রিমটি উন্মুক্ত ছেড়ে দেওয়ার সংক্ষিপ্ত জবাবটি এরকম হবে:using (var streamReader = new StreamReader(myStream, Encoding.UTF8, true, 1024, true))
beawolf

29

হ্যাঁ এটা করে. আপনি রিফ্লেক্টরের সাথে প্রয়োগটি দেখে এটি যাচাই করতে পারেন।

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {    
            this.stream = null;    
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}

13

ছয় বছর দেরীতে তবে সম্ভবত এটি কারও সাহায্য করবে।

স্ট্রিম রিডার নিষ্পত্তি হয়ে গেলে সংযোগটি বন্ধ করে দেয়। তবে, "স্ট্রিমরিডার / স্ট্রিম রাইটার দিয়ে (স্ট্রিম স্ট্রিম = ...) using ...}" ব্যবহার করে স্ট্রিমটি দু'বার নিষ্পত্তি হতে পারে: (1) যখন স্ট্রিমরেডার অবজেক্টটি নিষ্পত্তি করা হয় (2) এবং যখন স্ট্রিমটি ব্লক ব্যবহার করে স্ট্রিম ব্যবহার করে বন্ধ হয়ে যায়। ভিএস-এর কোড বিশ্লেষণ চলাকালীন এটি CA2202 সতর্কতার ফলস্বরূপ।

CA2202 পৃষ্ঠা থেকে সরাসরি নেওয়া আরেকটি সমাধান হ'ল চেষ্টা / শেষ অবধি ব্লক ব্যবহার করা। সঠিকভাবে সেটআপ করুন, এটি কেবল একবার সংযোগ বন্ধ করবে।

CA2202 এর নীচে , মাইক্রোসফ্ট নিম্নলিখিতগুলি ব্যবহার করার পরামর্শ দেয়:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

পরিবর্তে...

// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
    // Use the reader object...
}

2
সতর্কতাটি গ্রহণযোগ্য উত্তরের মন্তব্যেও আলোচনা করা হয়েছে। জন স্কিটি সেখানে কিছু পরামর্শ দেয়।
মার্সিন

এছাড়াও, সচেতন থাকুন যে ব্যবহারের বিবৃতিটি কম্পাইলার দ্বারা প্রকৃতপক্ষে একটি চেষ্টা-অবরুদ্ধ ব্লকে রূপান্তরিত হয়েছে।
জেসন কেলি

2

হ্যাঁ. কল অন ডিসপোজ () এবং আইডিস্পোজেবল (যা "ব্যবহার করে" করেন) কোনও বস্তুকে তার সমস্ত সংস্থান পরিষ্কার করতে হবে। এর মধ্যে স্ট্রিমগুলি ফ্লাশ করে এবং তাদের ফাইল বিবরণকারী বন্ধ করে includes

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


1

আপনার যদি প্রয়োজন হয় তবে এটি ঠিক করার একটি সহজ উপায় হ'ল স্ট্রিমাইটার ক্লাসগুলি নিষ্পত্তি করার পদ্ধতিটিকে ওভাররাইড করা। কোডটি কীভাবে করা যায় তার জন্য এখানে আমার পোস্টটি দেখুন:

।। একটি স্ট্রাইমাইটার লেখার অন্তর্নিহিত স্ট্রিমটি বন্ধ হয়?


-2

স্ট্রিমটি "কীওয়ার্ড" ব্যবহার করে বা স্পষ্টভাবে নিষ্পত্তি করে কল দিয়ে নিষ্পত্তি করা হয়

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