2017-04-07 9 views
2

내가 2013 년는 InternetReadFile을 버퍼를 작성하지만, 반환 0 바이트는

BOOL WWW::Read(char* buffer, DWORD buffer_size) 
{ 
    memset(buffer, 0, buffer_size); 
    m_dwBytesRead = 0; 

    BOOL bResult = InternetReadFile(m_handle, buffer, buffer_size, &m_dwBytesRead); 
    if (!bResult) 
    { 
     DWORD dwLastError = GetLastError(); 
     TCHAR *err; 

     if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 
      NULL, dwLastError, 
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language 
      (LPTSTR)&err, 0, NULL)) 
     { 
      LOGMSG(1, (TEXT("InternetReadFile failed at - (%u) %s\r\n"), dwLastError, err)); 
      LocalFree(err); 
     } 
    } 

    // FUDGE 
    if (m_dwBytesRead == 0) 
    { 
     DWORD dwZeros = countZeros(buffer, buffer_size); 
     if (dwZeros < buffer_size) 
     { 
      m_dwBytesRead = buffer_size; 
     } 
    } 
    // END OF FUDGE 

    return bResult; 
} 

나는 반복적으로 전화를 윈도우 컴팩트 위해 작성된 C++ 응용 프로그램 내에서 인터넷에서 파일을 다운로드하는 동안 아주 이상한 문제가있어 읽기 다른 멤버 함수의 기능 이상으로이 기능을 통해 처음 실패하고 후속 호출이 제대로 작동하지 않고 연한 캔디

DWORD dwWritten; 

while (!(Read(buffer, DOWNLOAD_BUFFER_SIZE) && m_dwBytesRead == 0)) 
{ 
    WriteFile(m_hDownload, buffer, m_dwBytesRead, &dwWritten, NULL); 
    m_dwActualSize += dwWritten; 
    ++m_dwChunks; 

    if (m_dwBytesRead > 0) 
     m_dwInactivity = 0; 
    else if (++m_dwInactivity > INACTIVITY_LIMIT) 
     return WDS_INACTIVITY; 
} 

따른다. 나는이 함수 호출을 통해 첫 번째 패스에서 얻을 오류가 나는 READ 작업 중 오류 "디스크에 공간이 부족합니다"는을 받고해야하는 이유 이해가 안

InternetReadFile failed at - (112) There is not enough space on the disk. 

입니다. 버퍼가 할당되고 사용 가능하며 예상되는 크기와 일치하는지 확인했습니다. 사실 버퍼의 내용을 검사 할 때 예상되는 바이트 수로 채워져 있지만 m_dwBytesRead 변수의 내용은 여전히 ​​0으로 설정되어 있습니다.

버퍼의 내용을 검사하여 코드가 채워 졌는지 확인한 다음 m_dwBytesRead 변수를 푸싱하여이 특정 사례를 중심으로 코딩 할 수 있지만 이는이 오류를 지나치게 임시로 해결하기위한 조치 일 뿐이며, 문제가 발생했습니다.

내 퍼지가 아닌이 오류의 결과는 데이터가 버려지고 첫 번째 블록이 누락되었지만 그렇지 않으면 완전히 수정 된 파일로 끝나는 것입니다. 따라서 MD5 검사가 실패하고 파일의 첫 번째 부분이 누락되었습니다.

파일이 항상 내가 사용하는 블록 크기보다 클 것이므로 퍼지 기능이 작동하지만 코드에서 이러한 끔찍한 해결 방법을 사용하는 것이 좋지 않습니다. 필요합니다.

누구든지 문제의 원인을 밝힐 수 있다면 크게 환영 할 것입니다. 난 비주얼 스튜디오 2013 C++ (네이티브 Windows 응용 프로그램이 아닌 MFC)를 사용하고

은, 대상이 2013 년

많은 감사, 32 비트 및 유니 코드 윈도우 컴팩트에서 실행 앤드류

+0

"일반"Windows에서 실행하면 어떻게됩니까? – Anders

+0

제안 해 주셔서 감사합니다. 나는 일반 창문에서 그것을 시도하지 않았다. 나는 확실히 그것을 (월요일에) 시험해보고 다른 행동이 있는지 알아볼 수있다. – pionium

+0

더 나은 해결 방법 (작동하는 경우)은 항상 첫 번째 읽기, 항상 길이가 0 인 읽기를 수행하는 것일 수 있습니다. –

답변

2

인가 실제로 디스크 공간이 부족한 머신? InternetReadFile은 기본적으로 뒤로 디스크에 기록합니다 :

응용 프로그램 함수가 TRUE를 반환하고 lpdwNumberOfBytesRead 매개 변수가 0 인 때까지의 InternetReadFile 함수를 호출하기 위해 계속해야, 모든 데이터가 검색되어 있는지 확인하십시오. 이는 요청 된 데이터가 캐시에 기록되는 경우 특히 중요합니다. 그렇지 않으면 캐시가 제대로 업데이트되지 않고 다운로드 된 파일이 캐시에 커밋되지 않기 때문입니다. 원래의 데이터 스트림 열기 요청이 INTERNET_FLAG_NO_CACHE_WRITE 플래그으로 설정되어 있지 않으면 캐싱이 자동으로 수행됩니다.

+0

공간 문제가 있다고 생각하지 않습니다. 실행중인 장치에는 현재 310MB가있는 500MB 플래시 드라이브가 있습니다. 그러나 이러한 다운로드에는 필요하지 않으므로이 작업에 캐시를 사용하지 않는 것이 좋습니다 **라고 생각합니다. 제안 해 주셔서 감사합니다. 분명히 이것을 (월요일에) 시험해보고 차이가 있는지 확인합니다. 나는 당신에게 알려줄 것이다 – pionium

+0

업데이트 :'InternetOpenUrl()'호출에'INTERNET_FLAG_NO_CACHE_WRITE' 플래그를 추가했지만, 슬프게도 아무런 효과가 없었다. 나는 여전히 "충분하지 않은 디스크 공간"오류가 발생합니다. 당분간 저는 제 일을 고수하고 있습니다. 솔루션을 발견하면 여기에 다시 게시하겠습니다. – pionium

+0

코드가 "정상적인"Windows에서 작동하는지 확인한 후 기능을 디버깅하거나 Microsoft에 문의하는 것이 좋습니다. – Anders