FTP檔案上傳demo
解決了在XP系統下面InternetConnect()介面在FTP伺服器不可用,連線超時嚴重,且不可控的問題。
該demo在WIN7 64 和XP 32 自測通過。
完整工程原始碼下載地址:
------------------------------------------------------------------------------------------
主要程式碼如下:
ftp.h
#pragma once #pragma warning(disable:4995) #include <strsafe.h> #include <process.h> #include <Wininet.h> #pragma comment(lib, "Wininet.lib") #include <vector> #include <string> using std::vector; using std::string; using std::wstring; #ifdef _UNICODE #define tstring wstring #else #define tstring string #endif // FTP配置引數 typedef struct tagFtpParam { int iFtpEnable; // 1開啟FTP上傳,0是關閉FTP上傳 TCHAR szFtpServerIp[32]; // FTP伺服器IP TCHAR szFtpUser[20]; // FTP登陸賬號 TCHAR szFtpPass[30]; // FTP登陸密碼 int iFtpPort; // FTP服務埠, 預設為21 int iFtpIsPassive; // 1表示FTP為被動模式,0表示FTP為主動模式 TCHAR szFtpUploadDir[30]; // FTP上傳目錄,如 /test tagFtpParam() { iFtpEnable = 0; ZeroMemory(szFtpServerIp, sizeof(szFtpServerIp)); ZeroMemory(szFtpUser, sizeof(szFtpUser)); ZeroMemory(szFtpPass, sizeof(szFtpPass)); iFtpPort = 21; iFtpIsPassive = 1; ZeroMemory(szFtpUploadDir, sizeof(szFtpUploadDir)); StringCbCopy(szFtpUploadDir, sizeof(szFtpUploadDir), _T("/test")); } }FtpParam; class CFtp { public: CFtp(void); ~CFtp(void); /** @name UploadDiskFile @brief 往FTP上傳磁碟檔案 @param[in] LPCTSTR pszFilePath, 磁碟檔案路徑 @param[in] LPCTSTR pszUploadDir, 上傳到的FTP目錄,以斜槓/開頭,如 /test @return 成功true,失敗false */ bool UploadDiskFile(LPCTSTR pszFilePath, LPCTSTR pszUploadDir); /** @name UploadMemoryFile @brief 往FTP上傳記憶體檔案 @param[in] PBYTE pbFile, 記憶體檔案緩衝區指標 @param[in] int iFileLen, 記憶體檔案長度 @param[in] LPCTSTR pszFileName, 儲存檔名稱 @param[in] LPCTSTR pszUploadDir, 上傳到的FTP目錄,以斜槓開頭,如/test @return bool */ bool UploadMemoryFile(PBYTE pbFile, int iFileLen, LPCTSTR pszFileName, LPCTSTR pszUploadDir); /** @name IsFileExists @brief 判斷檔案是否存在 @param[in]: LPCTSTR pszFilePath 檔案路徑 @return 檔案存在返回true, 否則返回false */ bool IsFileExists(LPCTSTR pszFilePath); public: FtpParam m_ftpParam; // ftp配置引數 private: /** @name ConnFtpServer @brief 連線FTP伺服器 @param[in] void @return 成功true,失敗false */ bool ConnFtpServer(void); // 連線FTP執行緒代理 static unsigned int _stdcall ThreadConnFtpProxy(PVOID pParam) { CFtp *pThis = (CFtp*)pParam; if (pThis != NULL) { pThis->ThreadConnFtp(); } return 0; } /** @name ThreadConnFtp @brief 連線FTP執行緒 @param[in] void @return bool */ bool ThreadConnFtp(void); private: HINTERNET m_hInetOpen; // 網路開啟控制代碼 HINTERNET m_hInetConn; // 網路連線控制代碼 HANDLE m_hConnThread; // 連線執行緒控制代碼 };
ftp.cpp
#include "StdAfx.h" #include "Ftp.h" CFtp::CFtp(void) { m_hInetOpen = NULL; m_hInetConn = NULL; m_hConnThread = NULL; } CFtp::~CFtp(void) { if (m_hInetOpen != NULL) { InternetCloseHandle(m_hInetOpen); m_hInetOpen = NULL; } if (m_hInetConn != NULL) { InternetCloseHandle(m_hInetConn); m_hInetConn = NULL; } if (m_hConnThread != NULL) { WaitForSingleObject (m_hConnThread, 1000*30); CloseHandle(m_hConnThread); m_hConnThread = NULL; } } /** @name ConnFtpServer @brief 連線FTP伺服器 @param[in] void @return 成功true,失敗false */ bool CFtp::ConnFtpServer(void) { WaitForSingleObject(m_hConnThread, 1000*60); m_hConnThread = (HANDLE)_beginthreadex(NULL, 0, ThreadConnFtpProxy, this, 0, NULL); DWORD dwTimeout = 1000*3; // 連線FTP超時時間 if (WaitForSingleObject (m_hConnThread, dwTimeout ) == WAIT_TIMEOUT) { TerminateThread(m_hConnThread, -1); if (m_hConnThread != NULL) { CloseHandle(m_hConnThread); m_hConnThread = NULL; } return false; } if (m_hConnThread != NULL) { CloseHandle(m_hConnThread); m_hConnThread = NULL; } return true; } /** @name UploadDiskFile @brief 往FTP上傳磁碟檔案 @param[in] LPCTSTR pszFilePath, 磁碟檔案路徑 @param[in] LPCTSTR pszUploadDir, 上傳到的FTP目錄,以斜槓/開頭,如 /test @return 成功true,失敗false */ bool CFtp::UploadDiskFile(LPCTSTR pszFilePath, LPCTSTR pszUploadDir) { if (pszFilePath == NULL || m_ftpParam.iFtpEnable == 0) { return false; } if (!IsFileExists(pszFilePath)) { return false; } if (!ConnFtpServer()) { return false; } // 解析上傳目錄 tstring strUploadDir; if (_tcslen(pszUploadDir) > 0) { strUploadDir = pszUploadDir; } else { strUploadDir = m_ftpParam.szFtpUploadDir; // 預設上傳目錄 } if (strUploadDir.size() <= 0) { strUploadDir = _T("/result/"); } strUploadDir[0] = _T('/'); // 確保以斜槓/開頭 if (strUploadDir[strUploadDir.size() - 1] != _T('/')) { strUploadDir += _T('/'); // 確保以斜槓/結尾 } // 確保上傳目錄存在 strUploadDir = /test tstring strCurDir = _T("/"); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); tstring strTmpDir = strUploadDir; bool bRet = true; while(strTmpDir.find(_T('/')) != tstring::npos && bRet) { size_t iStart = strTmpDir.find(_T('/')); strTmpDir.erase(iStart, 1); size_t iEnd = strTmpDir.find(_T('/')); tstring strDir = strTmpDir.substr(iStart, iEnd - iStart); bRet = FtpCreateDirectory(m_hInetConn, strDir.c_str()) > 0 ? true : false; strCurDir += strDir; strCurDir += _T('/'); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); if (iEnd == strTmpDir.size() - 1) { break; } } FtpSetCurrentDirectory(m_hInetConn, strUploadDir.c_str()); // 解析上傳磁碟檔名稱,如 D:\test.txt tstring strDiskFilePath = pszFilePath; tstring strDiskFileName; size_t iIndex = strDiskFilePath.rfind('\\'); if (iIndex != tstring::npos && iIndex >= 0) { strDiskFileName = strDiskFilePath.substr(iIndex+1, strDiskFilePath.size() - 1); } // 上傳磁碟檔案 tstring strTmpFile = strUploadDir; strTmpFile += strDiskFileName; bRet = FtpPutFile(m_hInetConn, pszFilePath, strTmpFile.c_str(), FTP_TRANSFER_TYPE_BINARY, NULL) > 0 ? true : false; // 獲取錯誤資訊 if (!bRet) { DWORD iErrorCode = GetLastError(); TCHAR szErr[1024] = {0}; DWORD dwLen = 1024; InternetGetLastResponseInfo(&iErrorCode, szErr, &dwLen); OutputDebugString(szErr); } return bRet; } /** @name UploadMemoryFile @brief 往FTP上傳記憶體檔案 @param[in] PBYTE pbFile, 記憶體檔案緩衝區指標 @param[in] int iFileLen, 記憶體檔案長度 @param[in] LPCTSTR pszFileName, 儲存檔名稱 @param[in] LPCTSTR pszUploadDir, 上傳到的FTP目錄,以斜槓開頭,如/test @return bool */ bool CFtp::UploadMemoryFile(PBYTE pbFile, int iFileLen, LPCTSTR pszFileName, LPCTSTR pszUploadDir) { if (pbFile == NULL || iFileLen < 1 || m_ftpParam.iFtpEnable == 0) { return false; } if (pszFileName == NULL) { return false; } if (!ConnFtpServer()) { return false; } // 解析上傳目錄 tstring strUploadDir; if (_tcslen(pszUploadDir) > 0) { strUploadDir = pszUploadDir; } else { strUploadDir = m_ftpParam.szFtpUploadDir; // 預設上傳目錄 } if (strUploadDir.size() <= 0) { strUploadDir = _T("/result/"); } strUploadDir[0] = _T('/'); // 確保以斜槓/開頭 if (strUploadDir[strUploadDir.size() - 1] != _T('/')) { strUploadDir += _T('/'); // 確保以斜槓/結尾 } // 確保上傳目錄存在 strUploadDir = /test tstring strCurDir = _T("/"); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); tstring strTmpDir = strUploadDir; bool bRet = true; while(strTmpDir.find(_T('/')) != tstring::npos && bRet) { size_t iStart = strTmpDir.find(_T('/')); strTmpDir.erase(iStart, 1); size_t iEnd = strTmpDir.find(_T('/')); tstring strDir = strTmpDir.substr(iStart, iEnd - iStart); bRet = FtpCreateDirectory(m_hInetConn, strDir.c_str()) > 0 ? true : false; strCurDir += strDir; strCurDir += _T('/'); FtpSetCurrentDirectory(m_hInetConn, strCurDir.c_str()); if (iEnd == strTmpDir.size() - 1) { break; } } FtpSetCurrentDirectory(m_hInetConn, strUploadDir.c_str()); // 解析上傳記憶體檔名稱 tstring strMemoryFileName = pszFileName; // 上傳記憶體檔案 HINTERNET hFtpFile = NULL; tstring strTmpFile = strUploadDir; strTmpFile += strMemoryFileName; hFtpFile = FtpOpenFile(m_hInetConn, strTmpFile.c_str(), GENERIC_WRITE, INTERNET_FLAG_TRANSFER_BINARY, NULL); if (hFtpFile != NULL) { DWORD dwWrite = 0; bRet = InternetWriteFile(hFtpFile, pbFile, iFileLen, &dwWrite) > 0 ? true : false; } // 獲取錯誤資訊 if (!bRet) { DWORD iErrorCode = GetLastError(); TCHAR szErr[1024] = {0}; DWORD dwLen = 1024; InternetGetLastResponseInfo(&iErrorCode, szErr, &dwLen); OutputDebugString(szErr); } // 釋放記憶體 if (hFtpFile != NULL) { InternetCloseHandle(hFtpFile); hFtpFile = NULL; } return bRet; } /** @name IsFileExists @brief 判斷檔案是否存在 @param[in]: LPCTSTR pszFilePath 檔案路徑 @return 檔案存在返回true, 否則返回false */ bool CFtp::IsFileExists(LPCTSTR pszFilePath) { if (pszFilePath == NULL) { return false; } HANDLE hRet = CreateFile(pszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); bool bRet = false; if (hRet != INVALID_HANDLE_VALUE ) // 檔案存在 { bRet = true; } CloseHandle(hRet); return bRet; } /** @name ThreadConnFtp @brief 連線FTP執行緒 @param[in] void @return bool */ bool CFtp::ThreadConnFtp(void) { if (m_hInetOpen != NULL) { InternetCloseHandle(m_hInetOpen); m_hInetOpen = NULL; } if (m_hInetConn != NULL) { InternetCloseHandle(m_hInetConn); m_hInetConn = NULL; } // 連線FTP 伺服器 //HINTERNET hInetOpen = InternetOpen(_T("CN"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC); // 非同步 m_hInetOpen = InternetOpen(_T("CN"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); // 同步 if (m_hInetOpen == NULL) { return false; } DWORD dwFlags = 0; if(m_ftpParam.iFtpIsPassive == 1) { dwFlags = INTERNET_FLAG_PASSIVE; } //DWORD dwTimeOut = 1000*3; // 超時值,經測試在WIN7有效,在XP無效,現已改成由執行緒控制 //InternetSetOption(m_hInetOpen, INTERNET_OPTION_CONNECT_TIMEOUT, &dwTimeOut, sizeof(dwTimeOut)); m_hInetConn = InternetConnect(m_hInetOpen, m_ftpParam.szFtpServerIp, m_ftpParam.iFtpPort, m_ftpParam.szFtpUser, m_ftpParam.szFtpPass, INTERNET_SERVICE_FTP, dwFlags, NULL); if (m_hInetConn == NULL) { return false; } return true; }
相關推薦
FTP檔案上傳demo
該demo主要是封裝了MS的Wininet.dll,方便FTP檔案上傳, 解決了在XP系統下面InternetConnect()介面在FTP伺服器不可用,連線超時嚴重,且不可控的問題。 該demo在WIN7 64 和XP 32 自測通過。 完整工程原始碼下載地址: --
Android關於FTP檔案上傳和下載功能詳解
Android關於FTP檔案上傳和下載功能詳解 更新時間:2017年09月21日 11:41:14 作者:一諾的祕密花園 我要評論 這篇文章主要為大家詳細介紹了Android關於FTP檔案上傳和下載功能,具有一定的參考價值,感興趣
webuploader如何使用,webuploader檔案上傳demo,使用webuploader上傳檔案
webuploader是百度開發的一個js上傳檔案的元件, 你可以免費使用它, 實現上傳檔案,圖片,壓縮包等。 由於webuploader官方文件都是講述前端,js怎麼使用, 很少提及到伺服器端的程式
【高效開發外掛】09 FTPUtil FTP 檔案上傳工具類
package com.yuu.mall.util; import org.apache.commons.net.ftp.FTPClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
Java 實現ftp 檔案上傳、下載和刪除
本文利用apache ftp工具實現檔案的上傳下載和刪除。具體如下: 1、下載相應的jar包 commons-net-1.4.1.jar 2、實現程式碼如下: public class FtpUtils { //ftp伺服器地址
寶塔-PHP-伺服器-資料庫-FTP-檔案上傳 問題集
簡介: 今天分享一下自己寫的筆記,最近部署伺服器所遇到的各種問題,比較典型的問題都寫在了筆記裡面,現在我把筆記分享給出來,希望可以給大家一點幫助~ 問題目錄: 1.寶塔設定 伺服器 本地資料庫、RDS雲資料庫 連線不上 2.寶塔設定 伺服器 FTP無法連線
centos6.5 ftp檔案上傳遇到的問題彙總
1、ftp 192.168.1.* -bash: ftp: command not found 解決方案:ftp命令沒有安裝 # yum install ftp 2、ftp: connect: 拒絕連線 解決方案: (1
java 中 FtpClient 實現 FTP 檔案上傳、下載
package ftp; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWrit
使用Socket 完成HTTP post方式的文字及檔案上傳 demo
程式碼結構: Android端 Web端 最終結果 該demo具有很強的通用性,而且程式碼的複用性極高,基本上以後不需要再為檔案上傳花費太多時間,拿過去直接可以用。 剛開始從
SWFUpload實現多檔案上傳DEMO
引言:最近專案中需要用到多檔案上傳,在網上找了很多資料,最開始使用的是uploadify這個外掛,在使用的過程中各種問題,什麼Flash版本的問題,瀏覽器相容性的問題總之是一大堆,最後在眾多問題下,無奈只好放棄了。最後選擇了SWFUpload,在網上下載了
shutil模組和幾種檔案上傳Demo
一、shutil模組 1、介紹 shutil模組是對os中檔案操作的補充。--移動 複製 打包 壓縮 解壓 2、基本使用 1. shutil.copyfileobj(檔案1, 檔案2, 長度) 將檔案1的資料覆蓋copy給檔案2,可以copy指定大小的內容 檔案1和2都是檔案
用ASP.NET的FileUpload控制元件實現帶對話方塊的FTP檔案上傳功能
最近不得已開始做網頁,一個ASP.NET的專案,需要實現FTP上傳功能,於是上網廣搜程式碼,發現FTP上傳的程式碼到處都是,隨手拈來,可是一般來說客戶端上傳檔案都需要一個檔案選擇對話方塊,正好自帶的FileUpload控制元件能夠實現。但是網上搜到FileUpl
java ftp檔案上傳下載刪除
package ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStre
十八.Python模擬FTP檔案上傳
Python 模擬FTP斷點續傳併發伺服器 #配置檔案 #伺服器配置檔案 [server_config] ip=127.0.0.1 port=8006 buffersize=1024 encoding=utf-8 #伺服器使用者資料
FTP檔案上傳
public class FTPUtil { private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class); private static String ftpIp = PropertiesUtil
java/struts/Servlet檔案下載與ftp檔案上傳下載
String s1=transUrl; // transUrl是前臺接受的引數,get接受的引數tomcat一律使用iso-8859-1編碼 transUrl=new String(transUrl.getBytes("ISO-8859-1"),"utf-8");//程式中要使用的檔名,必須轉換為gbk
java 檔案上傳demo
每次寫程式碼都要查詢,所以就放這裡面備份了 基本pom引用: <dependency> <groupId>org.apache.httpcomponents</groupId&
Shell FTP檔案上傳下載
1.上傳檔案到ftp 建立一個shell檔案:touch upload.sh 修改為可執行檔案:chmod +x upload.sh 編輯:vim upload.sh,指令碼內容如下 cd /user/directory/target export putfile=y
使用FileZilla連線Linux伺服器正常連線,但是無法上傳圖片[FTP檔案上傳]
使用FileZilla進行連線伺服器,不能上傳圖片的解決方式: 1.將要上傳到伺服器上的資料夾的許可權改為777,如chmod -R 777 /var/images 2.開啟vsftp
基於spring boot ftp檔案上傳
對ftp檔案上傳將行封裝,實現連線的單例模式,完成執行緒安全的改進,ftp檔案上傳下載失敗的重試。application.yml配置檔案ftp: ip: 127.0.0.1 port: 21 username: admin password: admi