الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تمرين بسيط حول الملفات في لغة C

بدأه Snack3r في 11 نوفمبر 2013 · 13 رد · 1,211 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

 

في هذا الموضوع أردتُ طرح سؤال بسيط حتى يُشارك الجميع.

السؤال :

اكتب دالة تستقبل مسار ملف معين عن طريق الـ command line و تُعيد عددا صحيحا يُمثل حجمه مع الأخذ في الاعتبار جميع الـ exceptions التي قد تنتج أثناء عمل الدالة.

 

 

 

 

بالتوفيق.

1
#2

شكرا لك أخي Snack3er

هذه محاولتي :

int fopen2()
{
    char path[200];
    printf("Enter File Path\n");
        scanf("%s",path);
    
    FILE *input=fopen(path,"rb");
    if(!input)
    {
        printf("Error Can't Open File ,maybe it's not exist or you don't have enough permittions , please call arabteam2000!\n");
    }
    else
    {
        int x=0;
        while(!feof(input))
            fgetc(input),x++;
        return x-1;
    }
    return 0;
}

ولكن ماهي الاستثناءات الأخرى غير عدم وجود الملف أو عدم التمكن من فتحه ؟

كما هل يمكن أن يكون path أطول 200 حرف ؟

#3
اقتباس
لكن ماهي الاستثناءات الأخرى غير عدم وجود الملف أو عدم التمكن من فتحه ؟

 

هذه هي الاستثناءات الخاصة بالدالة fopen, بقيت تلك الخاصة بـ close (في الحقيقة لا أدري لماذا تركتَ الباب مفتوحاً :P)

و fgetc أيضا.

 

 

اقتباس

 

هل يمكن أن يكون path أطول 200 حرف ؟

 

بالتأكيد, هذا مثال لأحد الملفات عندي :D

monDisqueDur:\InFoRmATiIQuE\programmation\langages de programmation\programmation orientée objet\langage Java\Mes Projets\NetBeans Projects\Débutants\performances réseaux\travaux pratiques à faire\matrices\matrice Stochastique\src\Dev\Stochastique.java
#4
monDisqueDur:\InFoRmATiIQuE\programmation\langages de programmation\programmation orientée objet\langage Java\Mes Projets\NetBeans Projects\Débutants\performances réseaux\travaux pratiques à faire\matrices\matrice Stochastique\src\Dev\Stochastique.java

يا الله، و انا أحاول قدر الإمكان استخدام اسماء صغيره حتى يكون المسار يسهل تتبعه:

L:\mathx\src\int\imp\le\default_logic.hpp

افتح الملف binary ثم نستخادم fseek و تمرير SEEK_END ثم نستخدام ftell للحصول على عدد bytes فى الملف.

 

لاحظ انه إذا كان الملف حجمه اكبر من 4 جيجا فستفشل هذه العملية حيث انه داخل ++C/C لم يتم تطوير المكتبات للتعامل مع الملفات ذات المساحة اكبر من 4 جيجا.

 

 

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#5

وهذه مشاركتي  على السريع , لم اجرب الكود بعد ( احتمال وجود اخطاء)

#ifdef UNICODE
typedef const wchar_t * spath;
 #else
typedef const char * spath;
#endif


unsigned int Getfilelen( spath path )
{
unsigned int flength = 0;
#if defined( WIN32 ) && defined ( UNICODE )
  FILE * f = _wfopen(path,L"r");
 #else //  linux or windows or ...
  FILE * f = fopen(path,"r");
#endif
if (!f)
{
  printf("could not open : %s \n",path);
}
 fseek(f,SEEK_SET,SEEK_END);
 flength = ftell(f);
 fclose(f);
 return flength;
}
#6

@C++er

بالنسبة لحجم الملف فتلك إحدى النقاط التي كنت أود الإشارة إليها :)

 

مثلا, الدالة التالية تُعيد 0 في حالة نجاح العملية و قيمة مخالفة للصفر في حالة الفشل, إذا كان بالإمكان حساب حجم الملف سيتم تخزينه في المؤشر ptr :

int fsize(const char * fname, long * ptr) {
    FILE * f;
    int ret = 0;
    f = fopen(fname, "rb");
    if (f != NULL) {
        fseek(f, 0, SEEK_END);
        *ptr = ftell(f);
        fclose(f);
    } else
        ret = 1;
    return ret;
}

المشكلة أن حجم الملف قد يتخطى القيمة العظمى لـ long و كما قال الأخ محمد إذا كان حجم الملف أقل من 4 جيجا يمكن حسابه و إلا فلا, مثال :

#include <windows.h>

int FileSize(const char * FileName, unsigned int * ptr) {
    WIN32_FILE_ATTRIBUTE_DATA attr;
    int ret = 0;
    if (GetFileAttributesEx(FileName, GetFileExInfoStandard, &attr)) {
        if (attr.nFileSizeHigh == 0) {
            *ptr = attr.nFileSizeLow;
        } else
            ret = 2;
    } else
        ret = 1;
    return ret;
}

@fouad2008

محاولة جيدة :)

 

 

 

تحياتي.

#7

داخل Windows يمكنك استخدام GetFileSize و تمرير المعامل الثاني NULL و ستساوى تماما الدالة FileSize مع العلم انه المفترض ان تعيد unsigned int و ليس int. و للملفات ذات المساحة الكبيرة - أكبر من 64بت - يمكن استخدام GetFileSizeEx.

 

 

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة C++er في 12 نوفمبر 2013 في 00:23

مدونتي: C++ Tips and Tricks

#8

النقاش صار متقدّماً , لماذا لا يمكن قراءة ملف أكبر من 4 غيغا ؟

إذا كانت المشكلة فقط :

اقتباس

المشكلة أن حجم الملف قد يتخطى القيمة العظمى لـ long

فيمكن حلّها بسهولة بالغة !

فهل هذه هي المشكلة الوحيدة ؟

#9
اقتباس

فيمكن حلّها بسهولة بالغة !

لا يمكن حلها بسهولة، لأن مكتبات اللغة نفسها سواء ++C او C لا يدعموا التعامل مع ملفات بمساحة تزيد عن 4 جيجا. و بالتالي ستحتاج لإستخدام ادوات نظام التشغيل و بهذا دخلنا فى موضوع منفصل.

 

اقتباس
فهل هذه هي المشكلة الوحيدة ؟

توجد مشاكل أخرى مثل shared files و Exclusive lock و لكن حلول مثل هذه المشاكل مرتبطه بنظام التشغيل بشكل كبير و من الصعب حلها بإستخدام الادوات التى توفرها اللغه.

 

 

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#10

أظن يمكن حلها بآستخدام sys/Stat.h، لكن بحثث داخل جهازي ولم أجد ملفاً أكبر من 4Gb حتى أجرب، الكود التالي غير مجرب

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

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

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

    return -1; 
}

int main (void)
{
	printf("%llu\n",fsize ("C:\\myFile.bin"));

	getchar ();
	return 0;
}

تم تعديل هذه المشاركة بواسطة zirek99i في 12 نوفمبر 2013 في 16:16

#11

لا لم يعمل ,, يرجع -1

#13

#include <sys/stat.h>

#include <stdio.h>

//#include <limits.h>

#include <string.h>

#define stat64 _stat64

int main (void)

{

//FILE *fptr = fopen ("largeFile", "a");

//char buffer [4096];

//memset(buffer, 0x41, sizeof(buffer));

//for(int v=0; v<5000000; v++)

//{

// //file allocation is 4096

// fwrite(buffer, sizeof(buffer), 1, fptr);

//}

/*fclose(fptr);*/

struct __stat64 st;

stat64( "C:\\Users\\oussama\\Desktop\\Memory_Pictures\\largeFile", &st );

printf("size: %llu\n", st.st_size);

getchar ();

return 0;

}

مواضيع مشابهة