【 開源:跨平臺網絡數據傳輸的萬能工具libcurl】

在當今這個互聯互通的世界中,數據在各種設備和平臺之間自由流動,而 libcurl,就像一把跨平臺的萬能工具,為開發者提供了處理各種網絡數據傳輸任務所需的強大功能。它不僅是一個庫,更是一種通用的解決方案,可以應對從桌面應用到嵌入式系統等各種場景的挑戰。

核心:libcurl 是什么?

libcurl 是一個免費、開源且高度可移植的客戶端 URL 傳輸庫 1。它支持廣泛的協議,包括 HTTP(S)、FTP(S)、SCP、SFTP、TFTP、TELNET、LDAP(S)、MQTT、IMAP、POP3、SMTP、RTMP 和 RTSP。這意味著,無論你的應用需要與哪種類型的網絡服務進行通信,libcurl 都能提供支持。

為什么 libcurl 如此受歡迎?

  • 廣泛的協議支持: libcurl 支持幾乎所有主流的網絡協議,使其成為處理各種數據傳輸場景的理想選擇 12。
  • 卓越的跨平臺能力: 這是 libcurl 最重要的特性之一。 無論你的應用運行在 Windows、Linux、macOS、iOS、Android、FreeBSD、OpenBSD 甚至是嵌入式系統上,libcurl 都能提供一致的 API 和功能 1。這極大地簡化了跨平臺應用的開發和維護。
  • 高度的靈活性和可定制性: libcurl 提供了大量的選項,允許你精細地控制數據傳輸的各個方面,例如超時時間、重試次數、SSL 證書驗證、HTTP 頭設置等等。
  • 卓越的性能: libcurl 使用 C 語言編寫,并經過了大量的優化,以提供卓越的性能。它還支持連接池、HTTP/2 和 HTTP/HTTP/3 等技術,進一步提升數據傳輸效率 2。
  • 強大的安全性: libcurl 支持 SSL/TLS 加密,并提供了各種安全選項,例如證書驗證、主機名驗證等,以確保數據傳輸的安全性。
  • 成熟度和穩定性: libcurl 已經存在了 20 多年,經過了無數項目的驗證,是一個非常成熟和穩定的庫 1。
  • 活躍的社區: libcurl 擁有一個龐大而活躍的社區,你可以從中獲得支持、分享經驗,并參與到 libcurl 的開發中。

libcurl 的高級特性 (不僅僅是下載文件)

  • 異步 API: libcurl 提供了異步 API,允許你在不阻塞主線程的情況下執行數據傳輸任務。這對于構建高性能的網絡應用至關重要。
  • 多路復用: libcurl 支持多路復用技術,允許你在單個連接上同時傳輸多個數據流。這可以顯著提高數據傳輸效率,尤其是在高并發場景下。
  • HTTP/2 和 HTTP/3: libcurl 支持最新的 HTTP/2 和 HTTP/3 協議,這些協議提供了更高的性能和更低的延遲。
  • WebSocket: libcurl 支持 WebSocket 協議,允許你構建實時的雙向通信應用。
  • 自定義協議處理: libcurl 允許你自定義協議處理程序,以支持非標準的或私有的協議。

libcurl 的常見使用場景 (從 FTP 客戶端到嵌入式系統)

  • 構建 FTP 客戶端: 使用 libcurl 可以輕松地實現一個功能完善的 FTP 客戶端,支持文件上傳、下載、目錄瀏覽等功能 15。
  • 開發 API 客戶端: 許多應用需要與各種 Web API 進行交互,例如獲取天氣信息、發送消息、支付等等。libcurl 可以幫助你輕松地發送 HTTP 請求,并處理 API 返回的數據。
  • 實現網絡爬蟲: 網絡爬蟲需要抓取大量的網頁內容。libcurl 可以幫助你高效地下載網頁,并處理 Cookie、重定向等問題。
  • 在物聯網 (IoT) 設備中使用: IoT 設備通常需要與云服務器進行通信,例如發送傳感器數據、接收控制指令等等。libcurl 可以被移植到各種嵌入式系統中,用于實現網絡數據傳輸功能。
  • 音視頻流媒體: libcurl 可以用于實現音視頻流媒體的客戶端,支持 HTTP Live Streaming (HLS)、Dynamic Adaptive Streaming over HTTP (DASH) 等協議。
  • 游戲開發: 在線游戲需要與游戲服務器進行通信,例如發送玩家的位置信息、接收游戲狀態更新等等。libcurl 可以用于實現這些網絡通信功能。
  • 金融交易系統: 金融交易系統需要與交易所進行通信,例如發送交易指令、接收市場數據等等。libcurl 可以用于實現這些網絡通信功能,并保證數據傳輸的安全性。

libcurl 的跨平臺特性及安裝使用

libcurl 的跨平臺特性是其最大的優勢之一。以下是在不同平臺下安裝和使用 libcurl 的簡要說明:

  • Windows:
    • 安裝: 可以從 https://curl.se/windows/ 下載預編譯的 libcurl 二進制文件。
    • 使用: 在 Visual Studio 等 IDE 中,需要配置包含目錄和庫目錄,并鏈接 libcurl.lib
  • Linux (Debian/Ubuntu):
    • 安裝: 使用 apt-get 命令安裝:sudo apt-get install libcurl4-openssl-dev
    • 使用: 在編譯時,需要鏈接 libcurl 庫:gcc your_program.c -lcurl
  • Linux (Red Hat/CentOS):
    • 安裝: 使用 yum 命令安裝:sudo yum install libcurl-devel
    • 使用: 在編譯時,需要鏈接 libcurl 庫:gcc your_program.c -lcurl

**libcurl 與 Qt 的完美結合 **

Qt 是一個強大的跨平臺應用開發框架,提供了豐富的 GUI 組件和網絡編程接口。雖然 Qt 提供了 QNetworkAccessManager 等網絡編程類,但在某些情況下,libcurl 仍然是更好的選擇。

  • 為什么在 Qt 中使用 libcurl?

    • 更底層的控制: libcurl 提供了更底層的控制,允許你精細地調整數據傳輸的各個方面。
    • 更廣泛的協議支持: libcurl 支持一些 QNetworkAccessManager 不支持的協議,例如 SCP、SFTP 等。
    • 某些特定場景下的性能優勢: 在某些特定場景下,libcurl 的性能可能優于 QNetworkAccessManager
  • 如何在 Qt 中使用 libcurl?

    1. 直接使用 libcurl 的 C API: 這是最常見的方式。你需要包含 curl/curl.h 頭文件,并鏈接 libcurl 庫。
    2. 使用 Qt 封裝的 libcurl 庫: 例如 QtilitiesKFTP。這些庫提供了更 Qt 風格的 API,使用起來更方便。
    3. 使用 QProcess 調用 curl 命令行工具: 這種方式比較簡單,但性能較差。
  • 示例代碼:

    1. 直接使用 libcurl 的 C API:

    #include <QCoreApplication>
    #include <QDebug>
    #include <curl/curl.h>
    #include <QFile>size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) {QFile *file = (QFile*)userp;return file->write((char*)buffer, size * nmemb);
    }int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);CURL *curl;CURLcode res;QFile file("output.txt");if (!file.open(QIODevice::WriteOnly)) {qDebug() << "Failed to open file for writing";return -1;}curl_global_init(CURL_GLOBAL_DEFAULT);curl = curl_easy_init();if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com");curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file);res = curl_easy_perform(curl);curl_easy_cleanup(curl);if(res == CURLE_OK) {qDebug() << "Download successful!";} else {qDebug() << "Error:" << curl_easy_strerror(res);}}curl_global_cleanup();file.close();return a.exec();
    }
    

    2. 使用 QProcess 調用 curl 命令行工具:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QProcess>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QProcess process;QString program = "curl"; // 確保 curl 命令在系統 PATH 中QStringList arguments;arguments << "https://www.example.com" << "-o" << "output.html";process.start(program, arguments);process.waitForFinished();QByteArray output = process.readAllStandardOutput();QByteArray error = process.readAllStandardError();if (!error.isEmpty()) {qDebug() << "Error:" << error;} else {qDebug() << "Output:" << output;qDebug() << "Download successful!";}return a.exec();
    }
    

深入剖析 libcurl 的核心概念

  • CURL easy handle:

    • 作用: easy handle 是 libcurl 中最基本的概念,它代表一個獨立的 HTTP(S)、FTP(S) 等協議的會話。你可以使用 easy handle 設置各種選項,例如 URL、請求方法、header、回調函數等。

    • 生命周期:

      1. 使用 curl_easy_init() 創建 easy handle。
      2. 使用 curl_easy_setopt() 設置 easy handle 的選項。
      3. 使用 curl_easy_perform() 執行數據傳輸。
      4. 使用 curl_easy_cleanup() 清理 easy handle。
    • 示例:

      CURL *curl = curl_easy_init();
      if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com");// ... 其他選項 ...CURLcode res = curl_easy_perform(curl);curl_easy_cleanup(curl);
      }
      
  • CURL multi handle:

    • 作用: multi handle 允許你同時管理多個 easy handle,實現并發傳輸。這可以顯著提高下載速度,尤其是在下載多個小文件時。

    • 工作原理: multi handle 使用事件驅動機制,通過 select() 或 poll() 等系統調用監聽 socket 事件,并在事件發生時調用相應的回調函數。

    • 示例:

      CURLM *multi_handle = curl_multi_init();
      CURL *easy_handle1 = curl_easy_init();
      CURL *easy_handle2 = curl_easy_init();curl_easy_setopt(easy_handle1, CURLOPT_URL, "https://www.example.com/file1.txt");
      curl_easy_setopt(easy_handle2, CURLOPT_URL, "https://www.example.com/file2.txt");curl_multi_add_handle(multi_handle, easy_handle1);
      curl_multi_add_handle(multi_handle, easy_handle2);int still_running = 0;
      do {CURLMcode mc = curl_multi_perform(multi_handle, &still_running);if(mc) {// 處理錯誤}// 等待 socket 事件// ...
      } while(still_running);curl_multi_remove_handle(multi_handle, easy_handle1);
      curl_multi_remove_handle(multi_handle, easy_handle2);
      curl_easy_cleanup(easy_handle1);
      curl_easy_cleanup(easy_handle2);
      curl_multi_cleanup(multi_handle);
      
  • CURL share handle:

    • 作用: share handle 允許你在多個 easy handle 之間共享會話信息,例如 Cookie、SSL 會話等。這可以避免重復的握手和認證過程,提高性能。

    • 線程安全: share handle 本身不是線程安全的,需要在多線程環境中使用鎖來保護共享資源。

    • 示例:

      CURLSH *share_handle = curl_share_init();
      curl_share_setopt(share_handle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
      curl_share_setopt(share_handle, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);CURL *easy_handle1 = curl_easy_init();
      CURL *easy_handle2 = curl_easy_init();curl_easy_setopt(easy_handle1, CURLOPT_SHARE, share_handle);
      curl_easy_setopt(easy_handle2, CURLOPT_SHARE, share_handle);// ...curl_easy_cleanup(easy_handle1);
      curl_easy_cleanup(easy_handle2);
      curl_share_cleanup(share_handle);
      
  • CURLcode:

    • 作用: CURLcode 是 libcurl 函數返回的錯誤碼,用于指示函數執行的結果。

    • 常見錯誤碼:

      • CURLE_OK (0): 一切正常。
      • CURLE_UNSUPPORTED_PROTOCOL (1): 不支持的協議。
      • CURLE_BAD_URL (2): URL 格式錯誤。
      • CURLE_COULDNT_RESOLVE_HOST (6): 無法解析主機名。
      • CURLE_COULDNT_CONNECT (7): 無法連接到服務器。
      • CURLE_HTTP_RETURNED_ERROR (22): HTTP 請求返回錯誤碼(例如 404、500)。
      • CURLE_SSL_CONNECT_ERROR (35): SSL 連接錯誤。
      • CURLE_OPERATION_TIMEDOUT (28): 操作超時。
    • 示例:

      CURLcode res = curl_easy_perform(curl);
      if(res != CURLE_OK) {std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
      }
      

7. 實際案例分析

  • 案例 1:開發一個簡單的 HTTP 客戶端

    這個案例演示了如何使用 libcurl 開發一個簡單的 HTTP 客戶端,可以發送 GET 和 POST 請求,并處理 HTTP 響應。

    #include <iostream>
    #include <string>
    #include <curl/curl.h>// 回調函數,用于接收 HTTP 響應數據
    size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *output) {size_t total_size = size * nmemb;output->append((char*)contents, total_size);return total_size;
    }int main() {CURL *curl;CURLcode res;std::string readBuffer;// 初始化 libcurlcurl_global_init(CURL_GLOBAL_DEFAULT);// 創建一個 curl handlecurl = curl_easy_init();if(curl) {// 設置要請求的 URLcurl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com");// 設置 write callback 函數curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);// 執行 HTTP 請求res = curl_easy_perform(curl);if(res != CURLE_OK) {std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;} else {std::cout << "HTTP Response:\n" << readBuffer << std::endl;}// 清理 curl handlecurl_easy_cleanup(curl);}// 清理 libcurlcurl_global_cleanup();return 0;
    }
    
  • 案例 2:實現一個多線程下載器 (簡要示例)

    這個案例演示了如何使用 libcurl 和 Qt 的多線程功能實現一個簡單的多線程下載器。由于完整的多線程下載器代碼較長,這里只提供一個簡要的示例,展示如何使用 curl_multi_perform 實現并發下載。

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <thread>
    #include <mutex>
    #include <curl/curl.h>// 下載任務結構體
    struct DownloadTask {std::string url;std::string filename;};// 下載函數void DownloadFile(DownloadTask task) {CURL *curl;FILE *fp;CURLcode res;curl = curl_easy_init();if (curl) {fp = fopen(task.filename.c_str(), "wb");if (fp) {curl_easy_setopt(curl, CURLOPT_URL, task.url.c_str());curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);res = curl_easy_perform(curl);fclose(fp);if (res != CURLE_OK) {std::cerr << "Download failed: " << curl_easy_strerror(res) << std::endl;} else {std::cout << "Download complete: " << task.filename << std::endl;}} else {std::cerr << "Failed to open file: " << task.filename << std::endl;}curl_easy_cleanup(curl);}}int main() {// 下載任務列表std::vector<DownloadTask> tasks = {{"https://www.example.com/file1.zip", "file1.zip"},{"https://www.example.com/file2.zip", "file2.zip"},{"https://www.example.com/file3.zip", "file3.zip"}};// 創建線程std::vector<std::thread> threads;for (auto &task : tasks) {threads.emplace_back(DownloadFile, task);}// 等待線程結束for (auto &thread : threads) {thread.join();}return 0;}```
  • 最佳實踐 (Qt + libcurl):

    • 使用 Qt 的信號和槽機制處理異步操作: 可以將 libcurl 的異步 API 與 Qt 的信號和槽機制結合使用,以實現非阻塞的網絡編程。
    • 使用 Qt 的數據類型: 可以使用 QByteArrayQString 等 Qt 的數據類型來處理 libcurl 返回的數據。
    • 注意線程安全: libcurl 不是完全線程安全的,需要在多線程環境中使用鎖來保護共享資源。
    • 選擇合適的封裝庫: 如果你希望使用更 Qt 風格的 API,可以考慮使用 QtilitiesKFTP 等封裝庫。
  • 使用場景示例:

    • 下載大文件: 使用 libcurl 可以更靈活地控制下載過程,例如支持斷點續傳、限速下載等。

    • 與 SCP/SFTP 服務器進行通信: QNetworkAccessManager 不支持 SCP/SFTP 協議,可以使用 libcurl 來實現這些功能。

    • 實現自定義的網絡協議: 如果你需要實現自定義的網絡協議,可以使用 libcurl 的自定義協議處理程序。

      libcurl 不僅僅是一個庫,它是一種思想,一種解決網絡數據傳輸問題的通用方法。無論你是開發桌面應用、移動應用、嵌入式系統還是其他類型的應用,libcurl 都能為你提供強大的支持,幫助你構建更高效、更安全、更可靠的網絡應用。掌握 libcurl 的使用,將使你成為一名更出色的跨平臺開發者。

參考鏈接

  • libcurl 官網: https://curl.se/libcurl/
  • curl 官網: https://curl.se/
  • curl GitHub 倉庫: https://github.com/curl/curl
  • libcurl tutorial: https://curl.se/docs/tutorial.html

以上部分內容由AI輔助整理完成,文中部分代碼暫未經過驗證,請謹慎使用。后續將持續更新代碼驗證情況。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81882.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81882.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81882.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ElasticSearch 8.x 快速上手并了解核心概念

目錄 核心概念概念總結 常見操作索引的常見操作常見的數據類型指定索引庫字段類型mapping查看索引庫的字段類型最高頻使用的數據類型 核心概念 在新版Elasticsearch中&#xff0c;文檔document就是一行記錄(json)&#xff0c;而這些記錄存在于索引庫(index)中, 索引名稱必須是…

優化 CRM 架構,解鎖企業競爭力密碼

引言 “在所有企業面臨的挑戰中&#xff0c;客戶關系管理無疑是最為關鍵的一環。” —— 彼得德魯克 在數字化浪潮席卷的當下&#xff0c;企業面臨著前所未有的機遇與挑戰。客戶關系管理&#xff08;CRM&#xff09;作為企業運營的核心環節&#xff0c;其架構的優劣直接影響著…

深入理解Docker和K8S

深入理解Docker和K8S Docker 是大型架構的必備技能&#xff0c;也是云原生核心。Docker 容器化作為一種輕量級的虛擬化技術&#xff0c;其核心思想&#xff1a;將應用程序及其所有依賴項打包在一起&#xff0c;形成一個可移植的單元。 容器的本質是進程&#xff1a; 容器是在…

list.forEach(s -> countService.refreshArticleStatisticInfo(s.getId())); 講解一下語法

這段代碼使用了Java中的forEach方法結合Lambda表達式來遍歷一個列表&#xff0c;并對列表中的每個元素執行特定操作。具體來說&#xff0c;它會遍歷列表中的每一個元素&#xff0c;并調用countService.refreshArticleStatisticInfo(s.getId())方法來刷新每個文章的統計信息。下…

AI開發者的算力革命:GpuGeek平臺全景實戰指南(大模型訓練/推理/微調全解析)

目錄 背景一、AI工業化時代的算力困局與破局之道1.1 中小企業AI落地的三大障礙1.2 GpuGeek的破局創新1.3 核心價值 二、GpuGeek技術全景剖析2.1 核心架構設計 三、核心優勢詳解?3.1 優勢1&#xff1a;工業級顯卡艦隊???3.2 優勢2&#xff1a;開箱即用生態?3.2.1 預置鏡像庫…

05算法學習_59. 螺旋矩陣 II

05算法學習_59. 螺旋矩陣 II 05算法學習_59. 螺旋矩陣 II題目描述&#xff1a;個人代碼&#xff1a;學習思路&#xff1a;第一種寫法&#xff1a;題解關鍵點&#xff1a; 個人學習時疑惑點解答&#xff1a; 05算法學習_59. 螺旋矩陣 II 力扣題目鏈接: 59. 螺旋矩陣 II 題目描…

JDK7Hashmap的頭插法造成的環問題

單線程下的擴容 多線程下的擴容 next&#xff1d;e 然后e的next變成e

JAVA|后端編碼規范

目錄 零、引言 一、基礎 二、集合 三、并發 四、日志 五、安全 零、引言 規范等級&#xff1a; 【強制】&#xff1a;強制遵守&#xff0c;來源于線上歷史故障&#xff0c;將通過工具進行檢查。【推薦】&#xff1a;推薦遵守&#xff0c;來源于日常代碼審查、開發人員反饋…

2025-05-21 Python深度學習5——數據讀取

文章目錄 1 數據準備2 Dataset2.1 自定義 Dataset2.2 使用示例 3 TensorBoard3.1 安裝3.2 標量可視化&#xff08;Scalars&#xff09;3.3 圖像可視化&#xff08;Images&#xff09;3.4 其他常用功能 4 transform4.1 ToTensor()4.2 Normalize()4.3 Resize()4.4 Compose()4.5 C…

5月21日學習筆記

MYSQL三層結構 表1 數據庫DB1 表2 數據庫管理系統 客戶端命令終端&#xff08;Dos&#xff09; DBMS 數據庫DB2 表1 表2 數據庫………. Mysql數據庫-表的本質仍然是文件 表的一行稱之為一條記錄->在java程序中一行記錄往往使用對象表示 SQL語…

二十、面向對象底層邏輯-ServiceRegistry接口設計集成注冊中心

一、服務治理的基石接口 在微服務架構中&#xff0c;服務實例的動態注冊與發現是保證系統彈性的關鍵機制。Spring Cloud Commons模塊通過ServiceRegistry與Registration接口定義了服務注冊的標準化模型&#xff0c;為不同服務發現組件&#xff08;Eureka、Consul、Nacos等&…

DeepSeek:以開源之力,引領AI技術新風潮

在年春節&#xff0c;大語言模型DeepSeek如同一枚震撼彈&#xff0c;在全球范圍內引發了轟動&#xff0c;成功“破圈”&#xff0c;將中國的人工智能&#xff08;AI&#xff09;技術成果推向了世界舞臺。 開源策略&#xff1a;打破技術壁壘 在AI行業&#xff0c;OpenAI等巨頭…

完整改進RIME算法,基于修正多項式微分學習算子Rime-ice增長優化器,完整MATLAB代碼獲取

1 簡介 為了有效地利用霧狀冰生長的物理現象&#xff0c;最近開發了一種優化算法——霧狀優化算法&#xff08;RIME&#xff09;。它模擬硬霧狀和軟霧狀過程&#xff0c;構建硬霧狀穿刺和軟霧狀搜索機制。在本研究中&#xff0c;引入了一種增強版本&#xff0c;稱為修改的RIME…

PyTorch可視化工具——使用Visdom進行深度學習可視化

文章目錄 前置環境Visdom安裝并啟動VisdomVisdom圖形APIVisdom靜態更新API詳解通用參數說明使用示例Visdom動態更新API詳解1. 使用updateappend參數2. ~~使用vis.updateTrace方法~~3. 完整訓練監控示例 Visdom可視化操作散點圖plot.scatter()散點圖案例線性圖vis.line()vis.lin…

Java使用Collections集合工具類

1、Collections 集合工具類 Java 中的 Collections 是一個非常有用的工具類&#xff0c;它提供了許多靜態方法來操作或返回集合。這個類位于 java.util 包中&#xff0c;主要包含對集合進行操作的方法&#xff0c;比如排序、搜索、線程安全化等。 Java集合工具類的使用&#x…

Unity基礎學習(五)Mono中的重要內容(1)延時函數

目錄 一、Mono中的延時函數Invoke 1. Invoke作用&#xff1a;延遲指定時間后執行一次函數。API&#xff1a; 2. InvokeRepeating作用&#xff1a;延遲后開始重復執行函數。API&#xff1a; 3. CancelInvoke作用&#xff1a;停止所有延時函數&#xff0c;或停止指定函數的延時…

180KHz 60V 5A開關電流升壓/升降壓型DC-DC轉換器XL4019升降壓芯片

介紹 XL6019是一款專為升壓、升降壓設計的 單片集成電路&#xff08;升壓和降壓是由外圍電路拓撲確定的&#xff09;&#xff0c;可工作在DC5V到40V輸入電 壓范圍&#xff0c;低紋波&#xff0c;內置功率MOS。XL6019內 置固定頻率振蕩器與頻率補償電路&#xff0c;簡化了電 路…

如何暢通需求收集渠道,獲取用戶反饋?

要暢通需求收集渠道、有效獲取用戶反饋&#xff0c;核心在于多樣化反饋入口、閉環反饋機制、用戶分層管理、反饋數據結構化分析等四個方面。其中&#xff0c;多樣化反饋入口至關重要&#xff0c;不同用戶有不同的溝通偏好&#xff0c;只有覆蓋多個反饋路徑&#xff0c;才能捕捉…

Python結合ollama和stramlit開發聊天機器人

Python結合ollama和stramlit開發聊天機器人 一、環境準備1、streamlit安裝2、langchain安裝3、ollama的安裝 二、Ollama平臺聊天機器人實現1、需求2、模型調用3、前端實現頁面呈現代碼實現 三、詳細代碼地址四、參考資源 一、環境準備 1、streamlit安裝 # 通過 pip 安裝 pip …

java jdbc執行Oracle sql文件

執行代碼 import java.io.FileInputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.sql.Connection; import java.sql.DriverManager;import org.apache.ibatis.jdbc.ScriptRunner;public class ExecSqlFileController {pu…