如果要在 Linux 從網路上下載檔案的話,可以使用 cURL。如果要在程式中使用的話,我們就需要它的函式庫版本-libcurl。
編譯與安裝
編譯需要的原始檔可以在官網下載。
其中一種下載方式是輸入指令:
- 下載:
wget https://curl.haxx.se/download/curl-7.54.1.tar.gz
- 解壓縮:
tar zxvf curl-7.54.1.tar.gz
在 Linux 下,依照官網指示,在原始碼所在的目錄下,輸入:
其中,make test
可以省略。
如果你的編譯器不是原來預設的那一個的話,也可以在 ./configure
或是 make
後面加上 flag,如
如果以後要更新的話,也是依照以上步驟。
編譯程式
我們用官網上的範例:10-at-a-time.c 編譯看看吧。 在檔案所在的資料夾輸入以下指令:
-lcurl
是 Options for Linking 。加上這個連結器才會去找 libcurl 這個函式庫。
使用
使用流程大致是這樣:
初始化>設定>執行>關閉
以 easy handle 來說,每個階段對應到的函式是
初始化:curl_easy_init()
設定:curl_easy_setopt()
執行:curl_easy_perform()
關閉:curl_easy_cleanup()
(handler 可以重複利用,全部使用完再清掉 handler 即可)
在設定中,有 3 個選項比較重要:
CURLOPT_URL:要取得的 url 位址
CURLOPT_WRITEFUNCTION:將接收資料的程式(的函式指標)
CURLOPT_WRITEDATA:資料將存入的空間指標(也可以說是將傳入 write function 的最後一個參數的指標)
當程式執行完 curl_easy_perform()
後,我們就可以從 CURLOPT_WRITEDATA 所設定的指標中取得我們要從網路上取得的資料了。
Write Function
得到資料後可以有 2 個方式處理
- 存檔
- 存到某個記憶體空間供後續使用
以下用 2 個範例說明上述 2 個狀況
- url2file.c :
write_data()
- htmltitle.cpp :
writer()
write_data()
的狀況比較單純。事先開好檔案,在函式用 fwrite,下載完關檔。
writer()
看起來也很簡單,先 new string,在函式中把資料 append 到 string,最後 string 中就是完整的資料。不過如果要改寫成字元指標呢?這樣的話就要先 malloc 一個空間,然後當資料進來的時候再 realloc 空間然後把新的資料複製到原本空間的後面囉。不過這一切有點複雜,幸好 Stack Overflow 上有範例可以參考:
[Stack Overflow] C libcurl get output into a string
簡單的例子
參考了上述的 url2file.c 寫了一個功能跟它差不多但更簡單一點的範例:
結語
這邊只簡單的在 easy interface 下經由 HTTP 協定從網路上下載一個網頁/檔案。如果要使用其他通訊協定,或是做其他更複雜的事情(如 multi interface)的話,官網上都有詳盡的文件可以參考。