سؤال

في تطبيق C++ الخاص بي، أحاول قراءة ملف ISO غير متزامن بواسطة createfile - مع العلم المتداخل وبعده - readfile.ولكن عندما أحاول هذا الرمز على ملف بسيط (ملف txt على سبيل المثال) فإنه يعمل.ولكن عندما أقوم بتشغيل هذا الرمز على ملف ISO - فإنه يفشل.لقد رأيت في MSDN أن الملف المضغوط لا يمكن قراءته إلا من خلال مكالمات مزامنة ملف القراءة.هل ملفات ISO موجودة في هذه الفئة؟إذا كانت الإجابة بنعم - هل لديك اقتراح آخر حول كيفية قراءة ملفات ISO غير المتزامنة؟

هذا هو الكود الخاص بي:

int _tmain(int argc, _TCHAR* argv[])
{


HANDLE hFile;
    DWORD NumberOfBytesRead = 0, dw;
    BYTE *buf = (BYTE*)malloc(BUF_SIZE*sizeof(BYTE));
    OVERLAPPED overlapped;
    overlapped.Offset = overlapped.OffsetHigh = 0;  
    memset(buf, 0, 1024);

overlapped.hEvent = CreateEvent(NULL, true, false, NULL); 
if(NULL == overlapped.hEvent)
    printf("error");

hFile = CreateFile("xxx.iso",
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING , 
                  NULL);



if (hFile == INVALID_HANDLE_VALUE)
        printf("invalid hfile\n");

   int i;   
   i= ReadFile(hFile,
                 buf,
                 BUF_SIZE,
                 &NumberOfBytesRead,
        &overlapped);
   if( GetLastError() == ERROR_IO_PENDING)
   {


       dw = WaitForSingleObject(overlapped.hEvent, INFINITE);
    if(dw ==  WAIT_OBJECT_0)
        if (GetOverlappedResult(hFile,&overlapped,&NumberOfBytesRead, TRUE) != 0)   
        {
            if (NumberOfBytesRead != 0) 
            {
                printf("!!!\n");
            }

        }

   }

شكرًا

هل كانت مفيدة؟

المحلول

لم تقم بنشر القيمة التي تستخدمها لـ BUF_SIZE ثابت، ولكن تأكد من أنه عدد صحيح مضاعف لحجم قطاع الحجم.يعد هذا خطأً شائعًا عند استخدام تدفقات الملفات غير المخزنة مؤقتًا.الوثائق ل FILE_FLAG_NO_BUFFERING في ال CreateFile() توثيق يقول:

هناك متطلبات صارمة للعمل بنجاح مع الملفات المفتوحة باستخدام CreateFile باستخدام علامة FILE_FLAG_NO_BUFFERING، لمزيد من التفاصيل، راجع التخزين المؤقت للملفات.

صفحة ملاحظات التخزين المؤقت للملف:

كما تمت مناقشته سابقًا ، يجب أن يفي التطبيق بمتطلبات معينة عند العمل مع الملفات التي تم فتحها مع file_flag_no_buffering.تنطبق التفاصيل التالية:

  • أحجام الوصول إلى الملفات، بما في ذلك إزاحة الملف الاختياري في البنية المتداخلة، إذا محدد ، يجب أن يكون لعدد من وحدات البايت التي هي مضاعف عدد صحيح لقطاع وحدة التخزين حجم.على سبيل المثال ، إذا كان حجم القطاع 512 بايت ، فيمكن للتطبيق طلب قراءات و يكتب 512 أو 1,024 أو 1,536 أو 2,048 بايت ، ولكن ليس من 335 أو 981 أو 7,171 بايت.

  • يجب أن تكون عناوين عازلة الوصول إلى الملفات لعمليات القراءة والكتابة محاذاة للقطاع الفعلي ، مما يعني محاذاة على العناوين في الذاكرة التي هي مضاعفات عدد صحيح في حجم القطاع الفعلي للحجم.اعتمادا على القرص ، قد لا يكون هذا المطلب القسري.

يجب على مطوري التطبيق أن يعلمنا أنواعًا جديدة من أجهزة التخزين التي يتم إدخالها في السوق بحجم قطاع الوسائط المادية البالغ 4،096 بايت.

على نظامي، هذه القيمة هي 4K وقراءة أي شيء أصغر من 4K في المرة الواحدة تؤدي إلى حدوث أخطاء.في العديد من نماذج التعليمات البرمجية الخاصة بشركة Microsoft، يكون 1K هو الحجم الافتراضي للمخزن المؤقت، لذلك يؤدي تعديل الأمثلة غالبًا إلى حدوث أخطاء في عمليات الإدخال/الإخراج غير المخزنة مؤقتًا.

يحرر:تأكد أيضًا من استبعاد جميع أعضاء OVERLAPPED بناء.لا تقم بتعيين Internal و InternalHigh الأعضاء إلى 0.قم دائمًا بمسح OVERLAPPED الهيكل على النحو التالي:

OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(OVERLAPPED));

وبعد ذلك، يمكنك تعيين إزاحة الملف ومقبض الحدث.

يحرر:ضع في اعتبارك أيضًا الملاحظة التالية حول lpNumberOfBytesRead المعلمة ل ReadFile():

استخدم NULL لهذه المعلمة إذا كانت هذه عملية غير متزامنة لتجنب النتائج الخاطئة المحتملة.[...] لمزيد من المعلومات، راجع قسم الملاحظات.

نصائح أخرى

أود أن أقترح إيلاء اهتمام خاص لحقول رمز الترقيم العام المتداخل وحقول رمز الترقيم العام المتراكب ، خاصة عند قراءة ملف بحجم يتخطى حدود عدد صحيح بدون إشارة يبلغ 32 بت.أعتقد أن المشكلة التي تواجهها كامنة هناك.

سيكون من الأفضل أن تتصل بـ GetLastError () كما قال Dodo حتى لو لم يكن هناك خطأ.ما سيعيده ReadFile سيكون مفيدًا جدًا.بقدر ما يتعلق الأمر بملفات ISO ، أعتقد أنها أنواع ملفات مضغوطة.يمكنك البحث لاستخدام وظيفة LzRead بالرغم من ذلك.ألقِ نظرة على هذا: "

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365226%28v=vs.85%29.aspx
".يمكنك أيضًا فتح الملف باستخدام LzOpenFile.Genacodicetagpre آمل أن يساعد.لا يمكن العثور على الكثير حول هذا الموضوع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top