আপনি কোন সি এর ফাইলের আকার নির্ধারণ করবেন?


137

আমি কীভাবে কোনও ফাইলের আকার বাইটে বের করতে পারি?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}

কোনও ফাইলের বিশদ পুনরুদ্ধার করতে আপনার একটি লাইব্রেরি ফাংশন ব্যবহার করতে হবে। যেহেতু সি সম্পূর্ণরূপে প্ল্যাটফর্মের স্বাধীন, আপনি কী প্ল্যাটফর্ম / অপারেটিং সিস্টেমের জন্য বিকাশ করছেন তা আমাদের জানানোর দরকার রয়েছে!
ক্রিস রবার্টস

কেন char* file, না কেন FILE* file? -1
মিস্টার অস্কার

-1 কারণ ফাইল ফাংশনগুলিকে ফাইল বর্ণনাকারী ফাইলগুলি গ্রহণ করা উচিত নয়
মিস্টার অস্কার

উত্তর:


144

নীলবজেক্টের কোডের ভিত্তিতে:

#include <sys/stat.h>
#include <sys/types.h>

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

পরিবর্তন করুন:

  • ফাইলনাম আর্গুমেন্ট ক const char
  • struct statসংজ্ঞাটি সংশোধন করে , যা ভেরিয়েবলের নামটি অনুপস্থিত।
  • এর -1পরিবর্তে ত্রুটিতে ফিরে আসে 0, যা খালি ফাইলের জন্য অস্পষ্ট। off_tএটি একটি সাইনড টাইপ তাই এটি সম্ভব।

আপনি যদি fsize()ত্রুটিতে কোনও বার্তা মুদ্রণ করতে চান তবে আপনি এটি ব্যবহার করতে পারেন:

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
    struct stat st;

    if (stat(filename, &st) == 0)
        return st.st_size;

    fprintf(stderr, "Cannot determine size of %s: %s\n",
            filename, strerror(errno));

    return -1;
}

32-বিট সিস্টেমে আপনার অপশনটি দিয়ে এটি সংকলন করা উচিত -D_FILE_OFFSET_BITS=64, অন্যথায় off_t2 GB অবধি মানগুলি ধরে রাখতে হবে। বিস্তারিত জানার জন্য লিনাক্সে লার্জ ফাইল সাপোর্টের "এলএফএস ব্যবহার" বিভাগটি দেখুন।


19
এটি লিনাক্স / ইউনিক্স নির্দিষ্ট - সম্ভবত এটি উল্লেখযোগ্য যে প্রশ্নটি কোনও ওএস নির্দিষ্ট করে নি।
ড্রয় হল

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

1
আরও পোর্টেবল কোডের জন্য, ডেরেকের প্রস্তাবিত হিসাবে fseek+ ব্যবহার করুন ftell
সিরো সান্তিলি :5 冠状 病 六四 事件 法轮功

9
আরও পোর্টেবল কোডের জন্য, ডেরেকের প্রস্তাবিত হিসাবে fseek+ ব্যবহার করুন ftell নং সি স্ট্যান্ডার্ড বিশেষভাবে যে fseek()করতে SEEK_ENDউপর একটি বাইনারি ফাইল অনির্ধারিত আচরণ। .1.১৯.৯.২ fseekফাংশন ... একটি বাইনারি স্ট্রিমের fseekSEEK_ENDঅর্থহীন সংখ্যার কলগুলি সমর্থন করার প্রয়োজন নেই , এবং নীচে উল্লিখিত হিসাবে, যা পাদদেশের পাদটীকা 234 থেকে রয়েছে। লিঙ্ক সি স্ট্যান্ডার্ড, এবং যা বিশেষভাবে লেবেলের 267 fseekথেকে SEEK_ENDঅনির্ধারিত আচরণ যেমন একটি বাইনারি প্রবাহে। ।
অ্যান্ড্রু হেনেল

74

ব্যবহার করবেন না int । 2 গিগাবাইটের চেয়ে বেশি আকারের ফাইলগুলি আজকাল ময়লা হিসাবে সাধারণ

ব্যবহার করবেন না unsigned int । 4 গিগাবাইটের চেয়ে বেশি আকারের ফাইলগুলি কিছুটা কম-সাধারণ-সাধারণ ময়লা হিসাবে সাধারণ

আইআইআরসি স্ট্যান্ডার্ড লাইব্রেরিটি off_tস্বাক্ষরবিহীন bit৪ বিট পূর্ণসংখ্যা হিসাবে সংজ্ঞায়িত করে , যা প্রত্যেককেই ব্যবহার করা উচিত। আমরা যখন কয়েক বছরের মধ্যে 16 টি এক্সাবাইট ফাইল ঝুলতে শুরু করি তখন আমরা কয়েক বছরের মধ্যে 128 বিট হিসাবে এটির নতুন সংজ্ঞা দিতে পারি।

আপনি যদি উইন্ডোতে থাকেন তবে আপনার getFileSizeEx ব্যবহার করা উচিত - এটি আসলে একটি স্বাক্ষরিত bit৪ বিট পূর্ণসংখ্যার ব্যবহার করে, সুতরাং তারা 8 এক্সাবাইট ফাইল দিয়ে সমস্যাগুলি আঘাত করা শুরু করবে। বোকা মাইক্রোসফ্ট! :-)


1
আমি সংকলকগুলি ব্যবহার করেছি যেখানে অফ_টি 32 বিট। মঞ্জুর, এটি এম্বেড থাকা সিস্টেমে যেখানে 4 জিবি ফাইল কম দেখা যায়। যাইহোক, পসিএক্স বিভ্রান্তি যোগ করার জন্য অফ 64__ টি এবং তার সাথে সম্পর্কিত পদ্ধতিগুলিও সংজ্ঞায়িত করে।
অ্যারন ক্যাম্পবেল

আমি সর্বদা উত্তরগুলি পছন্দ করি যা উইন্ডোজ ধরে নেয় এবং প্রশ্নটির সমালোচনা করা ছাড়া আর কিছুই করে না। আপনি কি দয়া করে এমন কিছু যুক্ত করতে পারেন যা পসিক্স-অনুগত?
এসএস অ্যানি

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

30

ম্যাট এর সমাধানটি সি এর পরিবর্তে সি ++ ব্যতীত কাজ করা উচিত এবং প্রাথমিক বলার প্রয়োজন নেই।

unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}

আপনার জন্যও আপনার বন্ধনী স্থির করে নিন। ;)

আপডেট: এটি সত্যিই সেরা সমাধান নয়। এটি উইন্ডোজ 4 জিবি ফাইলের মধ্যে সীমাবদ্ধ এবং এটি সম্ভবত GetFileSizeExবা প্ল্যাটফর্ম-নির্দিষ্ট কল ব্যবহারের চেয়ে ধীরে ধীরে ধীর stat64


হ্যাঁ তুমি পারবে. তবে, যদি না প্ল্যাটফর্ম-নির্দিষ্ট না লেখার সত্যিই বাধ্যতামূলক কারণ না পাওয়া যায় তবে আপনার সম্ভবত খোলা / সন্ধান-শেষ / বলুন / নিকটবর্তী প্যাটার্নের পরিবর্তে প্ল্যাটফর্ম-নির্দিষ্ট কলটি ব্যবহার করা উচিত।
ডেরেক পার্ক

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

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

1
সি 99 এবং সি 11 উভয়ই ফিরে long intআসে ftell()(unsigned long)ingালাই ফাংশন দ্বারা ইতিমধ্যে সীমিত হিসাবে পরিসীমা উন্নতি করে না। ftell()ত্রুটি -1 এ ফিরে আসুন এবং এটি কাস্টের সাথে আবদ্ধ হয়ে যান। সুপারিশ fsize()হিসাবে একই ধরনের আসতে ftell()
chux - মনিকা পুনরায় ইনস্টল করুন

আমি রাজী. Theালাই প্রশ্নের মূল প্রোটোটাইপটি মিলবে। যদিও আমি স্বাক্ষরযুক্ত স্বাক্ষরের পরিবর্তে কেন এটিকে স্বাক্ষরবিহীন দীর্ঘতে পরিণত করেছি তা আমি মনে করতে পারি না।
ডেরেক পার্ক

15

** এটি করবেন না ( কেন? ):

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

সংজ্ঞাটি ইন্টে পরিবর্তন করুন যাতে ত্রুটি বার্তাগুলি প্রেরণ করা যায় এবং তারপরে ব্যবহার করুন fseek()এবং ftell()ফাইলের আকার নির্ধারণ করুন।

int fsize(char* file) {
  int size;
  FILE* fh;

  fh = fopen(file, "rb"); //binary mode
  if(fh != NULL){
    if( fseek(fh, 0, SEEK_END) ){
      fclose(fh);
      return -1;
    }

    size = ftell(fh);
    fclose(fh);
    return size;
  }

  return -1; //error
}

5
@ মেঝাকা: সেই সিইআরটি রিপোর্টটি কেবল ভুল। fseekoএবং ftello( fseekএবং এবং ftellযদি আপনি পূর্ববর্তী ব্যতীত আটকে থাকেন এবং আপনি যে ফাইলের আকারের সাথে কাজ করতে পারেন তার সীমাতে খুশি হন) কোনও ফাইলের দৈর্ঘ্য নির্ধারণ করার সঠিক উপায়। statভিত্তিক সমাধানগুলি অনেকগুলি "ফাইল" (যেমন ব্লক ডিভাইস) তে কাজ করে না এবং পিসিক্স-ইশ সিস্টেমে বহনযোগ্য নয়।
আর .. গিথহাব বন্ধ করুন সহায়তা বরাদ্দে

1
নন-পিক্সিকস কমপ্লায়েন্ট সিস্টেমগুলিতে ফাইলের আকার পাওয়ার একমাত্র উপায় এটি (যেমন আমার খুব
স্বল্প বিস্মৃত

9

POSIX

POSIX মান ফাইলের আকার পেতে তার নিজস্ব পন্থা নেই। ফাংশনটি ব্যবহার
করতে sys/stat.hশিরোনাম অন্তর্ভুক্ত করুন ।

সংক্ষিপ্তসার

  • ব্যবহার করে ফাইলের পরিসংখ্যান পান stat(3)
  • প্রাপ্ত st_sizeসম্পত্তি।

উদাহরণ

দ্রষ্টব্য : এটি আকার সীমাবদ্ধ করে 4GB। যদি Fat32ফাইল সিস্টেম না হয় তবে 64 বিট সংস্করণটি ব্যবহার করুন!

#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    struct stat info;
    stat(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    struct stat64 info;
    stat64(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}

এএনএসআই সি (স্ট্যান্ডার্ড)

ANSI সি সরাসরি উপায় ফাইলের দৈর্ঘ্য নির্ধারণ উপলব্ধ নেই।
আমাদের আমাদের মন ব্যবহার করতে হবে। আপাতত, আমরা ব্যবহারের পদ্ধতিটি ব্যবহার করব!

সংক্ষিপ্তসার

  • ব্যবহার করে ফাইলটি শেষ পর্যন্ত সন্ধান করুন fseek(3)
  • ব্যবহার করে বর্তমান অবস্থানটি পান ftell(3)

উদাহরণ

#include <stdio.h>

int main(int argc, char** argv)
{
    FILE* fp = fopen(argv[1]);
    int f_size;

    fseek(fp, 0, SEEK_END);
    f_size = ftell(fp);
    rewind(fp); // to back to start again

    printf("%s: size=%ld", (unsigned long)f_size);
}

যদি ফাইল হয় stdinবা পাইপ হয়। পসিক্স, এএনএসআই সি কাজ করবে না। ফাইলটি যদি পাইপ বা হয় তবে এটি
ফিরে আসবে ।0stdin

মতামত : আপনি পরিবর্তে POSIX মান ব্যবহার করা উচিত । কারণ, এটির 64 বিট সমর্থন রয়েছে has


1
struct _stat64এবং __stat64()_ উইন্ডোগুলির জন্য।
বব স্টেইন

5

এবং যদি আপনি একটি উইন্ডোজ অ্যাপ্লিকেশন তৈরি করছেন তবে সিআরটি ফাইল আই / ও অগোছালো হিসাবে গেটফাইসাইজেক্স এপিআই ব্যবহার করুন , বিশেষত ফাইলের দৈর্ঘ্য নির্ধারণের জন্য, বিভিন্ন সিস্টেমে ফাইল উপস্থাপনায় অদ্ভুততার কারণে;)


5

যদি আপনি স্ট্যান্ড সি লাইব্রেরি ব্যবহার করে ভাল থাকেন:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

24
এটি স্ট্যান্ডার্ড সি নয় এটি পসিক্স স্ট্যান্ডার্ডের অংশ, তবে সি স্ট্যান্ডার্ড নয়।
ডেরেক পার্ক

3

গুগলে একটি দ্রুত অনুসন্ধান fseek এবং ftell ব্যবহার করে একটি পদ্ধতি খুঁজে পেয়েছে এই প্রশ্নের উত্তর সহ একটি থ্রেড যে এটি কেবল সিতে অন্য কোনও উপায়ে করা যায় না।

আপনি এনএসপিআর (লাইব্রেরি যা ফায়ারফক্সকে শক্তি দেয়) এর মতো বহনযোগ্য লাইব্রেরি ব্যবহার করতে পারেন বা এর বাস্তবায়ন (বরং লোমশ) পরীক্ষা করতে পারেন ।


1

আমি ফাইলের দৈর্ঘ্য সন্ধান করতে কোডের এই সেটটি ব্যবহার করেছি।

//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");

//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);

//stores file size
long file_length = buffer.st_size;
fclose(i_file);

1

এটা চেষ্টা কর --

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

এটি প্রথমে যা করে তা ফাইলের শেষের দিকে চেষ্টা করুন; তারপরে, ফাইল পয়েন্টারটি কোথায় রয়েছে তা রিপোর্ট করুন। শেষ পর্যন্ত (এটি optionচ্ছিক) এটি ফাইলটির শুরুতে ফিরে আসে। মনে রাখবেন যেfp বাইনারি স্ট্রিম হওয়া উচিত।

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


3
8 বছর আগের ডেরেকের উত্তর থেকে এটি কীভাবে আলাদা ?
পিপি

এটি বাইনারি স্ট্রিমের জন্য অপরিবর্তিত আচরণ, এবং একটি পাঠ্য স্ট্রিমের ftellজন্য ফাইল থেকে পড়া যায় এমন বাইটের সংখ্যার কোনও মান প্রতিনিধি ফেরায় না।
অ্যান্ড্রু হেনেল

0

আমার একটি ফাংশন রয়েছে যা কেবলমাত্র সাথে ভালভাবে কাজ করে stdio.h। আমি এটি অনেক পছন্দ করি এবং এটি খুব ভালভাবে কাজ করে এবং বেশ সংক্ষিপ্ত:

size_t fsize(FILE *File) {
    size_t FSZ;
    fseek(File, 0, 2);
    FSZ = ftell(File);
    rewind(File);
    return FSZ;
}

0

এখানে একটি সাধারণ এবং পরিষ্কার ফাংশন যা ফাইলের আকার দেয়।

long get_file_size(char *path)
{
    FILE *fp;
    long size = -1;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size = ftell(fp); 
    fp.close();
    return 
}

1
আপনার কি ফাইলটি বন্ধ করার দরকার নেই?
জেরি যিরমিয়

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

-3

আপনি ফাইলটি খুলতে পারেন, ফাইলটির নীচে থেকে আপসেট 0 টিতে যান

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

fseek থেকে প্রাপ্ত মানটি ফাইলের আকার।

আমি দীর্ঘ সময় সি তে কোড করি নি, তবে আমার মনে হয় এটির কাজ করা উচিত।


12
আপনার সেকবটম এর মতো কিছু সংজ্ঞায়িত করতে হবে না। # অন্তর্ভুক্ত <stdio.h> fseek (হ্যান্ডেল, 0, SEEK_END);
সিগজুইস

-4

প্রশ্নটি দেখে ftellসহজেই বাইটের সংখ্যা পেতে পারেন।

  long size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

ftellআর্গুমেন্ট হিসাবে কোনও ফাইল বর্ণনাকারী, কোনও ফাইলের নাম নয়।
বার্মার

বার্মার, নো ftellকোনও ফাইল বর্ণনাকারী প্রত্যাশা করে না, FILE*পরিবর্তে এটি প্রত্যাশা করে। ম্যান পেজটি আগে দেখুন!

পদ্ধতির সম্পূর্ণরূপে ভুল, এটি ধ্রুবক যা প্রতিবার ftellফিরে আসবে 0!

এই উত্তরটি আউট ভুল সমতল এক জন্য হিসাবে, আপনি ব্যবহার করতে হবে, fseek()প্রথম ফাইলের শেষে চাইতে এবং এছাড়াও, ftell()একটি আশা FILE *, না একটি স্ট্রিং! আপনার উত্তরটি ভালভাবে পরিবেশন করা হবে।
মিস্টার অস্কার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.