none
c++ 로 파일을 어떻게 읽어야 하는지요? RRS feed

  • 질문

  •  

    어떤 파일을 읽어서 데이타 파싱을 해서 읽고 싶습니다.

    가령 읽을려고 하는 파일 구조가

    DWORD(데이타 길이) + 데이타  이렇게 되어 있다고 가정하고

    ////////////////////////////////////////////////////////////////////////

    일반적인 c, c++ 코딩 방식

    ///////////////////////////////////////////////////////////////////////

    보통 fopen 또는 CreatFile , fread, ReadFile api 를 사용해서

    fp = fopen(filename, "rb");

    while (!fp)

    {

        DWORD dw;

        fread(&dw, sizeof(DWORD), 1);

        if (dw == 0)

           break;

        char * buf = new char[dw];

        fread(buf, dw, 1);

    }

    flcose(fp);

    ////////////////////////////////////////////////

    메트로 앱에서 비동기 방식

    /////////////////////////////////////

    FileOpenPicker ^ hat_open_picker =
      ref new FileOpenPicker();
     hat_open_picker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
     hat_open_picker->FileTypeFilter->Append(".jpg");
     hat_open_picker->FileTypeFilter->Append(".jpeg");
     hat_open_picker->FileTypeFilter->Append(".png");
     hat_open_picker->ViewMode = PickerViewMode::Thumbnail;

     hat_open_picker->CommitButtonText = "Open";
     task<StorageFile ^>(hat_open_picker->PickSingleFileAsync()).then([this](StorageFile ^file)
     {

      if (file != nullptr)
      {
       String ^ str = file->Name;
       String ^ path = file->Path;
       int a = 0;
         create_task(file->OpenAsync(FileAccessMode::Read)).then([=](IRandomAccessStream^ stream)
         {
        int64 dwsize = stream->Size;
        IInputStream ^ is = stream->GetInputStreamAt(0);
        DataReader ^ dataReader = ref new DataReader(is);

        create_task(dataReader->LoadAsync(dwsize)).then([this, dataReader](unsigned int numBytesLoaded)
        {

            while (1)  ===>???????????

           {

             int dw = dataReader->ReadInt32();

            if (dw == 0)

                break;

         //Platform::Array<byte>^ fileContent = ref new Platform::Array<byte>(numBytesLoaded);
         //dataReader->ReadBytes(fileContent);     

         Platform::Array<byte>^ data = ref new Platform::Array<byte>(dw);

         dataReader->ReadBytes(data);

         }

         delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed
        });
         });
      }
      else
      {
      }
     });

    1. 데이타를 읽을때는  이렇게 하면 되는건지요?

    2.  질문이 요상하지만 저 While 문을 안에서 처리를 했는데

       파일사이즈가 만약 4기가 라 하면 즉 큰파일 인경우 어떻게 처리를 해야 하는것인지 감이 안잡힙니다.

    3. dataReader->LoadAsync , DataReader 의 관계 개념

    4. LoadAsync 를 계속 호출해야 할것 같은데 어떻게 하는건지 ?

    5. 좀 복잡한 파일을 파싱할때 zip 이나 뭐 이런파일들 파일 구조를 읽고 seek 를 해야 할때

        seek 는 IRandomAccessStream 에 있는데 어떻게 제어를 해야 하는지 ?

    기존에는

    그냥 thread 생성해서 안에서 fread(ReadFile), fseek, SetFilePosition 를 사용해서 했는데 ...

    비동기 방식이라 너무헷갈리네요

     

     

     

    도움좀 부탁드리겠습니다.

     



    • 편집됨 albert.kay69 2012년 10월 4일 목요일 오전 10:44
    • 이동됨 Jina Lee 2012년 10월 23일 화요일 오전 5:46 (이전 위치:Windows 스토어 앱)
    2012년 10월 4일 목요일 오전 10:37

답변

  • //자문 자답이지만

    // 이렇게 하면 될것 같네요

     task<StorageFile ^>(hat_open_picker->PickSingleFileAsync()).then([this](StorageFile ^file)
     {
      if (file != nullptr)
      {
       String ^ str = file->Name;
       String ^ path = file->Path;
       int a = 0;
       create_task(file->OpenAsync(FileAccessMode::Read)).then([=](IRandomAccessStream^ stream)
       {
    #if 1 

    //#include <Shcore.h>
    // lib  shcore.lib
        ComPtr<IStream> iss;
                    CreateStreamOverRandomAccessStream(stream, __uuidof(IStream), &iss);
        char ch;
        LARGE_INTEGER li;
        li.QuadPart = 0;
        ULONG cbreaded;
        iss->Read(&ch, 1, &cbreaded);
        iss->Read(&ch, 1, &cbreaded);
        iss->Read(&ch, 1, &cbreaded);
        iss->Read(&ch, 1, &cbreaded);
        iss->Seek(li, STREAM_SEEK_SET, NULL);
        iss->Read(&ch, 1, &cbreaded);
    #else
    //  문제는 seek 를 어떻게 해야 될지 모르겠네요!!!!
        IInputStream ^ is = stream->GetInputStreamAt(0);
        int64 dwsize = stream->Size;
        DataReader ^ dataReader = ref new DataReader(is);
        while (1)
        {
        auto l = dataReader->LoadAsync(4096);
        auto t = create_task(l).then([this, dataReader, stream](unsigned int numBytesLoaded)
        {
         //Platform::Array<byte>^ fileContent = ref new Platform::Array<byte>(numBytesLoaded);
         //dataReader->ReadBytes(fileContent);
         char ch;
         int n;
         n = dataReader->UnconsumedBufferLength;
         ch = dataReader->ReadByte();
         int a = 0;
        });

        t.wait();
        int b = 0;
        }
    #endif
         }, task_continuation_context::use_arbitrary());
      }
      else
      {
      }
     });
    }

     더나은 방법이 있다면 응답추가 해주십시요...

    • 답변으로 제안됨 Jina Lee 2012년 11월 1일 목요일 오전 4:45
    • 답변으로 표시됨 Jina Lee 2012년 11월 1일 목요일 오전 4:45
    2012년 10월 5일 금요일 오전 6:02