2009-04-14 6 views
9

Win32에서 .NET없이 C++을 사용하고 있습니다. 휠을 다시 발명 할 필요없이 웹 사이트에서 HTTP를 통해 이미지를 다운로드하려면 어떻게해야합니까? 이 작업을 수행하는 단일 기능을 제공하는 API 또는 라이브러리가 있습니까?URL에서 로컬 디렉토리로 이미지를 다운로드하는 방법은 무엇입니까?

http://mywebsite/file.imgext -> C : \ 경로 \ 디렉토리 \ file.imgext

+2

대부분의 답변에서 n 당신을 만족시키지 마십시오. 아마도 질문은 적절하게 요구되지 않을 것입니다. 다음 내용을 확인하기 전에 확인하십시오. http://www.catb.org/~esr/faqs/smart-questions.html –

+1

내가 무례하다고 생각하는 이유는 무엇입니까? 나는 바퀴를 다시 발명 해줄 해결책을 찾고 있습니다. 20 줄을 쓰는 것은 바퀴를 재발 명하고, 6 줄을 쓰는 것은 그렇지 않습니다. 너 자신을 변호 할 필요가 없어. 너에게 무례한 것이 내 의도가 아니야. –

+0

당신은 어떤 합리적인 답을 밝히고, 당신이 그것에 대해 아는 논점을 가지고 있거나 그것을 시도했습니다. 그래서, 질문 자체가 정확하지 않습니다. 당신이 Q에 넣은 많은 정보와 같이 유용한 답을 얻을 수 있습니다 (링크를 확인하십시오, 많은 가치가 있습니다). –

답변

7

당신은 아직 그것을 사용 havn't는 cURLpp

사용할 수있다 (그리고, 소스를 사용할 수도없는 경우. 당신은 그것을 구현되어 어떻게 볼 수 있습니다 볼 수 있습니다)하지만 해결할 수처럼 example20 본다 너의 문제.

+0

libcurl이 먼저 시도되었으므로 충돌이 발생하고 C++ 버전을 인식하지 못합니다. 예, 우리가 가지고있는 첫 번째 코드와 동일한 스타일을 6 행으로 수행합니다. –

+0

왜 충돌이 발생 했습니까? 라이브러리가 얼마나 보편적으로 사용 되었는가에 따라, 나는 그 버그가 당신 것이 아닌 것으로 생각하고 있습니다. –

+0

libcurl을 win32 DLL로 사용하는 경우 CURLOPT_WRITEDATA를 설정하면 CURLOPT_WRITEFUNCTION을 사용해야합니다. 그렇지 않으면 충돌이 발생합니다. ==> 휠을 다시 발명하도록 안내합니다. –

2

사용 Windows Http Services API를 \합니다.

+0

이렇게하면 버퍼링 된 스트림을 사용하여 연결을 열고, 통신하고, 다운로드하고 파일에 쓸 수 있어야합니다. 이 작업을 수행하는 더 쉬운 방법이 없습니까? 다른 언어에서도 한 줄을 사용하여이 작업을 수행 할 수 있습니다. –

+0

무례 행동은 무례한 반응을 불러옵니다. 다른 언어를 사용하십시오. –

+0

Btw, 언어가 아니에요, 도서관 이니까 ... –

1

새 프로세스를 시작하는 것이 정상이면 WGET을 볼 수 있습니다.

+0

글쎄, 그것은 빠른 해결책이지만 효율적이지 못하며 오버 헤드가 발생합니다. –

2

C++에서 WinInet 또는 WinHTTP 클래스를 사용할 수 있습니다. 이것들은 네이티브 Win32 API로서, 인터넷에서 파일을 보내고받는 작업의 추상적 인 일부입니다.

저는 WinInet을 사용하여 수행하려는 작업을 성공적으로 수행했습니다.

+0

이렇게하면 버퍼링 된 스트림을 사용하여 연결을 열고, 통신하고, 다운로드하고 파일에 쓸 수 있어야합니다. –

+0

FTP 전송을 위해 WinInet을 사용하는 Microsoft의 샘플 코드는 다음과 같습니다. http://support.microsoft.com/kb/q238273/ – CLaRGe

+0

FTP 기능이있는 클라이언트를 작성해야하는 경우 계속 기억하십시오. 감사합니다. 여전히 HTTP를 통해 로컬 하드 디스크로 파일을 다운로드하는 작업을 다시해야합니다. –

0

POCO을 지금 사용 중입니다. :-)

6

에서 WinInet API를 사용하면 다음

완전한 Win32 콘솔 프로그램입니다 생각하는 것보다 쉽다. VS 2010 Express 및 WinINit을 얻는 Windows SDK 다운로드로 구축 할 수 있습니다.


// imaged.cpp : Defines the entry point for the console application. 
// 
// Copy file from internet onto local file 
//  Uses Wininet API 
// program takes 1 mandatory command line argument - URL string 
// it downloads ito the current directory, or whatever is passed 
// as the second parameter to DownloadURLImage. 
// optional parameter, the name of the file (excluding path), by default it uses the 
// filename from the URL string. 

#include "stdafx.h" 
#include <iostream> 
#include <windows.h> 
#include <WinInet.h> // from SDK 
#include "string.h" 
//#include<TCHAR.H> 
//#include "Tchar.h" 
using namespace std ; 

int convertURLtofname (TCHAR * szURL, TCHAR * szname) 
// extract the filename from the URL 
{ 
    char aszfilename [100]; 
    HRESULT result; 
    char achar[3], aszURL [100]; 
    size_t nchars, i, j; 
    int fresult; 

    fresult = 0; 

    nchars= _tcslen(szURL); 
    i= nchars -1; 
    while ((i > 0) && (szURL[i] != '/') && (szURL[i] != '\\')) {i--;} 
    j= 0; i++; 
    while (i < nchars) { szname [j++]= szURL[i++]; } 
    szname[j]=_T('\0'); 

// wcstombs (aszfilename, szname, 100); 
//  cout << aszfilename << endl; 
//---------------------------------------------- 
    return fresult ; 
} 

int determinepathfilename (TCHAR * szURL, TCHAR * szpath, TCHAR * szname, TCHAR * szpathfilename) 
{ 
// use path and filename when supplied. If filename (e.g. funkypic.jpg) is not supplied, then the 
// filename will be extracted from the last part of the URL 
    int result ; 
    result= 0; 
    TCHAR szname_copy [100] ; 

     if ((szname == NULL) || (szname[0] == '\0')) 
      convertURLtofname (szURL, szname_copy); 
     else 
      _tcscpy (szname_copy, szname); 

     if ((szpath == NULL) || (szpath[0] == '\0')) 
       _tcscpy (szpathfilename, szname_copy); 
     else 
     { 
      _tcscpy (szpathfilename, szpath); 
      _tcscat (szpathfilename, szname_copy); 
     } 
    return result ; 
} 

bool GetFile (HINTERNET hOpen, // Handle from InternetOpen() 
        TCHAR *szURL,  // Full URL 
        TCHAR * szpath, 
        TCHAR * szname) 
{ 
    DWORD dwSize; 
    TCHAR szHead[15]; 
    BYTE * szTemp[1024]; 
    HINTERNET hConnect; 
    FILE * pFile; 
    TCHAR szpathfilename [100] ; 

    szHead[0] = '\0'; 

    if (!(hConnect = InternetOpenUrl(hOpen, szURL, szHead, 15, INTERNET_FLAG_DONT_CACHE, 0))) 
    { 
     std::cout << "Error: InternetOpenUrl" << std::endl; 
     return 0; 
    } 

    determinepathfilename (szURL, szpath, szname, szpathfilename); 

    if (!(pFile = _tfopen (szpathfilename, _T("wb")))) 
    { 
     std::cerr << "Error _tfopen" << std::endl; 
     return false; 
    } 
    do 
    { 
     // Keep copying in 1024 bytes chunks, while file has any data left. 
     // Note: bigger buffer will greatly improve performance. 
     if (!InternetReadFile (hConnect, szTemp, 1024, &dwSize)) 
     { 
      fclose (pFile); 
      std::cerr << "Error InternetReadFile" << std::endl; 
      return FALSE; 
     } 
     if (!dwSize) 
      break; // Condition of dwSize=0 indicate EOF. Stop. 
     else 
      fwrite(szTemp, sizeof (BYTE), dwSize , pFile); 
    } // do 
    while (TRUE); 
    fflush (pFile); 
    fclose (pFile); 

    return TRUE; 
} 

int DownloadURLImage (TCHAR * szURL, TCHAR * szpath, TCHAR * szname) 
{ int result ; 

    HINTERNET hInternet; 

    result= 0; 

    hInternet= InternetOpen (_T("imaged"), 
           INTERNET_OPEN_TYPE_DIRECT, //__in DWORD dwAccessType 
           NULL,      //__in LPCTSTR lpszProxyName, 
           NULL,      //__in LPCTSTR lpszProxyBypass, 
           NULL      //_in DWORD dwFlags 
          ); 

    GetFile (hInternet, szURL, szpath, szname) ; 
    InternetCloseHandle(hInternet); 
    return result ; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    if (argc == 2) 
    { 
     DownloadURLImage (argv[1], NULL, NULL); 
     //DownloadURLImage (argv[1], _T"C:/", NULL); 
    } 
    else if (argc == 3) 
    { 
     DownloadURLImage (argv[1], NULL, argv[2]); 
     //DownloadURLImage (argv[1], _T"C:/", argv[2]); 
    } 
    else 
    { 
     cout << "Usage: imaged <image URL>" << endl ; 
    } 
    system("pause") ; 
    return 0; 
} 
+0

좋은 예. GetFile() 함수에서 한 가지 수정이 필요합니다. 바이트 * szTemp [1024]; 는 BYTE szTemp [1024]이어야합니다. 대신. szTemp는 바이트 배열이며 바이트 포인터의 배열이 아니어야합니다. –

2

당신이 쉬운 솔루션을 원하고 보안 걱정을하지 않는 경우, 이것은 놀랍게도 간단 하나 라이너를 사용 : Windows 용 wget과 함께

system("C:\\Users\\Me\\Desktop\\wget.exe http://pixelcaster.com/yosemite/webcams/ahwahnee2.jpg -O C:\\Users\\Me\\Desktop\\ahwahnee2.jpg"); 

choco install wget 

참조 chocolatey.org

관련 문제