ফ্রেড / ফ্রিটাইট আকার এবং আর্গুমেন্ট হিসাবে গণনা করার যুক্তি কী?


96

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

বিনামূল্যে থেকে (3) :

ফাংশন ফ্রেড () স্ট্রিম দ্বারা নির্দেশিত স্ট্রিম থেকে পিটিআর দ্বারা প্রদত্ত স্থানে স্টোর করে প্রতিটি আকারের বাইট লম্বা করে ডেটাগুলির নামফল উপাদানগুলি পড়ে।

ফাংশন ফায়ারাইট () প্রতিটি পিটিং পিটিআর দ্বারা প্রদত্ত অবস্থান থেকে প্রাপ্ত স্ট্রিমের প্রতি স্ট্রমে নির্দেশিত স্ট্রমে প্রতিটি আকার বাইট লম্বা করে নাম্বার উপাদানগুলি লিখে দেয়।

fread () এবং fwrit () সাফল্যের সাথে পড়া বা লিখিত আইটেমের সংখ্যা (যেমন, অক্ষরের সংখ্যা নয়) ফিরিয়ে দেয়। যদি কোনও ত্রুটি দেখা দেয় বা ফাইলটির শেষের দিকে পৌঁছে যায়, ফেরতের মানটি একটি ছোট আইটেম গণনা (বা শূন্য)।


10
আরে এটি একটি ভাল প্রশ্ন। আমি সর্বদা এটি সম্পর্কে ভাবতাম
জোহানেস স্কাউব -

4
দয়া করে এই থ্রেডটি দেখুন: স্ট্যাকওভারফ্লো
ফ্রাঙ্কেন

উত্তর:


22

এটি ফ্রেড কীভাবে কার্যকর করা হয় তার উপর ভিত্তি করে ।

একক ইউনিক্স স্পেসিফিকেশন বলে

প্রতিটি বস্তুর জন্য, আকার কলগুলি fgetc () ফাংশনে এবং সঞ্চিত ফলাফলগুলিতে অর্ডারে, স্বাক্ষরিত চরের বিন্যাসে হুবহু অবজেক্টটিকে ওভারলাইং করা হবে।

fgetc এছাড়াও এই নোট আছে:

যেহেতু fgetc () বাইটগুলিতে পরিচালনা করে, একাধিক বাইট (বা "একটি বহু-বাইট অক্ষর") সমন্বিত একটি অক্ষর পড়তে fgetc () এ একাধিক কল প্রয়োজন হতে পারে।

অবশ্যই, এটি ইউটিএফ -8 এর মতো অভিনব পরিবর্তনশীল-বাইট অক্ষর এনকোডিংগুলির পূর্বাভাস দেয়।

এসইউএস নোট করে যে এটি আসলে আইএসও সি নথি থেকে নেওয়া হয়েছে।


72

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


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

4
যদি ন্যায়সঙ্গততা সম্পন্ন হয় তবে এটি দুর্দান্ত উত্তর দেবে।
ম্যাট যোগদানকারী

14

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

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


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

9

এখানে, আমাকে সেই ফাংশনগুলি ঠিক করতে দিন:

size_t fread_buf( void* ptr, size_t size, FILE* stream)
{
    return fread( ptr, 1, size, stream);
}


size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
{
    return fwrite( ptr, 1, size, stream);
}

fread()/ এর পরামিতিগুলির পক্ষে যুক্তি হিসাবে fwrite(), আমি আমার কে & আর এর অনুলিপিটি অনেক আগে হারিয়েছি যাতে আমি কেবল অনুমান করতে পারি। আমি মনে করি যে সম্ভবত উত্তরটি হ'ল কর্নিগান এবং রিচি কেবল ভেবেছিলেন যে বাইনারি আই / ও সম্পাদন করা সবচেয়ে স্বাভাবিকভাবে বস্তুর অ্যারেতে করা হবে। এছাড়াও, তারা ভেবে থাকতে পারে যে ব্লক আই / ও প্রয়োগ করা আরও দ্রুত / সহজ হবে বা কিছু স্থাপত্যের যা কিছু হোক না কেন।

যদিও সি স্ট্যান্ডার্ড তা নির্দিষ্ট করে fread()এবং এর fwrite()ক্ষেত্রে প্রয়োগ করা হয় fgetc()এবং fputc()মনে রাখবেন যে সি ও কেআরআর দ্বারা সংজ্ঞায়িত হওয়ার অনেক পরে স্ট্যান্ডার্ডটি অস্তিত্ব লাভ করেছিল এবং স্ট্যান্ডার্ডে নির্দিষ্ট করা জিনিসগুলি মূল ডিজাইনারদের ধারণাগুলিতে নাও থাকতে পারে। এমনকি এটিও সম্ভব যে কে ও আর এর "দ্য সি প্রোগ্রামিং ল্যাঙ্গুয়েজ" এ বলা জিনিসগুলি ভাষাটি প্রথম ডিজাইন করার সময় একই রকম নাও হতে পারে।

অবশেষে, fread()"স্ট্যান্ডার্ড সি লাইব্রেরি" তে পিজে প্লুগারের কী কথা বলা হয়েছে তা এখানে :

যদি size(দ্বিতীয়) যুক্তি এক তার চেয়ে অনেক বেশী হয়, তাহলে আপনি নির্ধারণ পারছে না যে ফাংশন এছাড়াও পর্যন্ত পড়েছেন size - 1তা রিপোর্ট পরলোক অতিরিক্ত অক্ষর। একটি নিয়ম হিসাবে, আপনি ফাংশন fread(buf, 1, size * n, stream);পরিবর্তে হিসাবে কল করা ভালfread(buf, size, n, stream);

মূলত, তিনি বলছেন যে fread()এর ইন্টারফেসটি নষ্ট হয়ে গেছে। কারণ fwrite()তিনি নোট করেছেন যে, "লেখার ত্রুটিগুলি সাধারণত বিরল, তাই এটি কোনও বড় ঘাটতি নয়" - এমন একটি বিবৃতি যার সাথে আমি একমত নই।


17
আসলে আমি প্রায়শই এটি অন্যভাবে করা পছন্দ করি: fread(buf, size*n, 1, stream);অসম্পূর্ণ পাঠগুলি যদি ত্রুটির শর্ত freadহয় তবে কেবল বাইটের সংখ্যা পড়ার চেয়ে 0 বা 1 ফেরত দেওয়ার ব্যবস্থা করা সহজ । তারপরে আপনি if (!fread(...))অনুরোধ সংখ্যক বাইটের (যার জন্য অতিরিক্ত সি কোড এবং অতিরিক্ত মেশিন কোড প্রয়োজন) এর সাথে ফলাফলের তুলনা করার পরিবর্তে আপনি কিছু করতে পারেন ।
আর .. গিথহাব বন্ধ করুন ICE

4
@ আর ..! ফ্রেড (...) ছাড়াও সেই আকার * গণনা! = 0 যাচাই করে নিন! যদি আকার * গণনা == 0 হয় তবে আপনি একটি সফল পঠন (শূন্য বাইটের), ফিফ () এবং ফেরার () নির্ধারণ করতে পারবেন না, এবং এর্নো ENOENT এর মতো বাজে কিছু হবে, বা আরও খারাপ EAGAIN এর মতো বিভ্রান্তিমূলক কিছু (এবং সম্ভবত সমালোচনামূলকভাবে ভেঙে দেওয়া) - খুব বিভ্রান্তিকর, বিশেষত যেহেতু মূলত কোনও ডকুমেন্টেশন আপনাকে এই গোচাতে চিৎকার করে না।
পেগাসাস এপসিলন

3

সম্ভবত ফাইলটি I / O প্রয়োগ করা হয়েছিল এমন পথে ফিরে যায়। (ফিরে এসেছিল) ব্লকগুলিতে ফাইলগুলিতে লেখা / পড়ার জন্য একবারে সবকিছু লিখতে আরও দ্রুত হতে পারে।



1

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

আমি জানি না কী পরিমাণে ফ্রেডের প্রয়োগগুলি এই জাতীয় শব্দার্থবিজ্ঞান পরিচালনা করতে পারে তবে তারা অবশ্যই বাস্তবায়নে কার্যকর হতে পারে যা তাদের সমর্থন দেওয়ার প্রতিশ্রুতি দিতে পারে।


@ পেগাসাসেপসিলন: উদাহরণস্বরূপ যদি কোনও প্রোগ্রামটি করে fread(buffer, 10000, 2, stdin)এবং ব্যবহারকারী যদি ১৮,০০০ বাইট টাইপ করার পরে নিউলাইন-সিটিআরএল-ডি টাইপ করেন, তবে ফাংশনটি প্রথম 10,000 বাইটগুলি ফিরিয়ে আনতে পারত যদি ভবিষ্যতে ছোট পড়ার অনুরোধের জন্য বাকী ৮,০০০ মুলতুবি থাকত তবে সেখানে থাকত কোন বাস্তবায়ন কোথায় হবে? ভবিষ্যতের সেই অনুরোধগুলি মুলতুবি করে 8,000 বাইট কোথায় সংরক্ষণ করা হবে?
সুপারক্যাট 27'19

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

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

তবুও আমি আমার পূর্ববর্তী মন্তব্যটি অপূর্ণতার কারণে মুছে ফেলেছি। আচ্ছা ভালো.
পেগাসাস এপসিলন

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

0

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

এই বিবেচনা:

int intArray[10];
fwrite(intArray, sizeof(int), 10, fd);

বাইটের স্বাক্ষরিত সংখ্যার লিখিত চিহ্ন লিখলে আপনি নিম্নলিখিতটি লিখতে পারেন:

int intArray[10];
fwrite(intArray, sizeof(int)*10, fd);

তবে এটি কেবল অদক্ষ। আপনার মাপের (ইনট) আরও বেশি বার কল হবে।

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

কিছু সিস্টেমে (প্রান্তিককরণের কারণে) আপনি অনুলিপি তৈরি এবং স্থানান্তর না করে একটি পূর্ণসংখ্যার এক বাইট অ্যাক্সেস করতে পারবেন না।

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