【C#】Ftp/Http资源上传下载(支持断点续传) + IIS http/ftp服务器
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
1. IIS资源服务器部署2. Http资源下载,支持断点续传2.1 获取资源下载大小
/// <summary> /// 获取文件大小 /// </summary> /// <param name="url"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static long GetDownloadFileSize(string url, string userName = "", string password = "") { try { url = HttpUtility.UrlPathEncode(url); var req = (HttpWebRequest)WebRequest.Create(url); req.Method = WebRequestMethods.Http.Head; req.Credentials = new NetworkCredential(userName, password); req.Timeout = 1000; req.Credentials = new NetworkCredential(userName, password); var res = (HttpWebResponse)req.GetResponse();
long rl = 0; if (res.StatusCode == HttpStatusCode.OK) { rl = res.ContentLength; } res.Close(); return rl;
} catch { }
return 0; } 2.1 资源下载,并且支持断点续传/// <summary> /// 下载文件(支持断点续下) /// </summary> /// <param name="url"></param> /// <param name="desDir">本地文件夹路径</param> /// <param name="overwrite">覆盖下载</param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <param name="callback">进度回调</param> /// <returns></returns> public static bool DownloadFile(string url, string desDir,bool overwrite = false, string userName = "", string password = "",Action<long,long> callback = null) { string fileName = Path.GetFileName(url); if (string.IsNullOrEmpty(desDir)) { //路径为空,设置文件名 desDir = fileName; } else { if (!Directory.Exists(desDir)) { //文件夹不存在,创建新文件夹 Directory.CreateDirectory(desDir); }
//路径连接 desDir = Path.Combine(desDir, fileName); }
//编码Url url = HttpUtility.UrlPathEncode(url); long downloadFileSize = GetDownloadFileSize(url, userName, password); if (downloadFileSize <= 0) { //下载文件异常 callback?.Invoke(-1, -1); return false; }
bool flag = false; long curPosition = 0; Stream stream = null; FileStream fileStream = null; //下载未完成之前存为临时文件(支持断点续下) string tmpFile = desDir + ".temp";
try { //下载文件已存在 if (File.Exists(desDir)) { var fileInfo = new FileInfo(desDir); curPosition = fileInfo.Length; if (curPosition >= downloadFileSize) { //覆盖进行删除重新下载 if (overwrite) { File.Delete(desDir); } else { callback?.Invoke(downloadFileSize, downloadFileSize); return true; } } } } catch {
}
try { //临时文件存在 if (File.Exists(tmpFile)) { fileStream = File.OpenWrite(tmpFile); curPosition = fileStream.Position;
if (curPosition >= downloadFileSize) { //不覆盖 if (!overwrite) { if (fileStream != null) { fileStream.Close(); fileStream.Dispose(); } //重命名 File.Move(tmpFile, desDir); callback?.Invoke(downloadFileSize, downloadFileSize); return true; } curPosition = 0; }
callback?.Invoke(curPosition, downloadFileSize); fileStream.Seek(curPosition, SeekOrigin.Current); } else { fileStream = new FileStream(tmpFile, FileMode.Create, FileAccess.Write); curPosition = 0; }
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); httpWebRequest.Credentials = new NetworkCredential(userName, password); if (curPosition > 0) { //断点续下,将请求下载的字节流下载位置设置成上次下载位置 httpWebRequest.AddRange(curPosition); } long downloadSize = curPosition; var res = httpWebRequest.GetResponse(); string totalLength = FormatSize(res.ContentLength, 2); stream = res.GetResponseStream(); byte[] buffer = new byte[4096]; int byteReader = 0; do { //读取, 写入本地 byteReader = stream.Read(buffer, 0, buffer.Length); downloadSize += byteReader; callback?.Invoke(curPosition, downloadFileSize); fileStream.Write(buffer, 0, byteReader); } while (byteReader != 0);
//下载完成 callback?.Invoke(downloadFileSize, downloadFileSize); res.Close(); flag = true; } catch (Exception e) { callback?.Invoke(-1, -1); } finally { if (fileStream != null) { fileStream.Flush(); fileStream.Close(); fileStream.Dispose(); } if (stream != null) { stream.Dispose(); stream.Close(); } if (flag) { //临时文件重命名 File.Move(tmpFile, desDir); } } return flag; } 3. Ftp资源上传下载,支持断点续传3.1 检测ftp是否可连接/// <summary> /// 检测ftp是否登录 /// </summary> /// <param name="url"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static bool CheckFtp(string url, string userName = "", string password = "") { try { //编码Url url = HttpUtility.UrlPathEncode(url); FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(url); request.Method = WebRequestMethods.Ftp.ListDirectory; request.Credentials = new NetworkCredential(userName, password); request.Timeout = 3000;//3秒超时
FtpWebResponse ftpWebResponse = (FtpWebResponse)request.GetResponse(); Stream responseStream = ftpWebResponse.GetResponseStream();
responseStream.Close(); ftpWebResponse.Close();
return true; } catch (Exception ex) { return false; } } 3.2 获取文件大小/// <summary> /// 获取文件大小 /// </summary> /// <param name="url"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static long GetDownloadFileSize(string url, string userName = "", string password = "") { try { url = HttpUtility.UrlPathEncode(url); FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Credentials = new NetworkCredential(userName, password); ftpWebRequest.Method = WebRequestMethods.Ftp.GetFileSize; ftpWebRequest.UseBinary = true; FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse(); Stream stream = ftpWebResponse.GetResponseStream(); long fileSize = ftpWebResponse.ContentLength; stream.Close(); ftpWebResponse.Close(); return fileSize; } catch (Exception ex) { } return 0; } 3.3 创建文件夹,支持多级目录创建/// <summary> /// 创建文件夹 /// </summary> /// <param name="url"></param> /// <param name="newDir"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static bool MaskDirectory(string url, string newDir, string userName = "", string password = "") { //创建新文件夹为空 if (string.IsNullOrEmpty(newDir)) { return true; }
string targetUrl = HttpUtility.UrlPathEncode(url + "/" + newDir); //检测远端文件夹是否存在 bool check = CheckFtp(targetUrl, userName, password); if (check) { //存在 return true; }
//多级文件夹处理(例如:x/xx/xxx/xxxx) string[] dirs = newDir.Replace("\\", "/").Split('/'); int length = dirs.Length; if (length <= 1) { //一级文件夹,直接创建 return _MaskDirectory(url, targetUrl, userName, password); }
//多级文件夹,分级创建, StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < length; i++) { if (string.IsNullOrEmpty(dirs[i])) { continue; }
stringBuilder.Append(dirs[i]); targetUrl = stringBuilder.ToString(); //检查当前文件夹是否存在 check = CheckFtp(url + "/" + targetUrl, userName, password); if (check) { continue; }
//进行创建 bool flag = _MaskDirectory(url, targetUrl, userName, password); if (!flag) { return false; }
stringBuilder.Append("/"); }
return true; } /// <summary> /// 创建文件夹 /// </summary> /// <param name="url"></param> /// <param name="newDir">新文件夹</param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> private static bool _MaskDirectory(string url, string newDir, string userName = "", string password = "") { if (string.IsNullOrEmpty(newDir)) { return true; } try { url = HttpUtility.UrlPathEncode(url + "/" + newDir); FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Method = WebRequestMethods.Ftp.MakeDirectory; ftpWebRequest.KeepAlive = false; ftpWebRequest.UseBinary = true; ftpWebRequest.Credentials = new NetworkCredential(userName, password);
FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse(); Stream stream = ftpWebResponse.GetResponseStream();
stream.Close(); ftpWebResponse.Close(); return true; } catch (Exception ex) { } return false; } 3.4 删除文件夹/// <summary> /// 传出文件夹 /// </summary> /// <param name="url"></param> /// <param name="delDir"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> private static bool _RemoveDirectory(string url, string delDir, string userName = "", string password = "") { try { url = HttpUtility.UrlPathEncode(url + "/" + delDir); FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Method = WebRequestMethods.Ftp.RemoveDirectory; ftpWebRequest.KeepAlive = false; ftpWebRequest.Credentials = new NetworkCredential(userName, password);
FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse(); Stream stream = ftpWebResponse.GetResponseStream();
stream.Close(); ftpWebResponse.Close(); return true; } catch (Exception e) { } return false; } 3.5 文件上传(支持断点续传)/// <summary> /// 上传文件 /// </summary> /// <param name="url">ftp地址</param> /// <param name="localfile">本地文件名</param> /// <param name="remotePath">远传的文件名</param> /// <param name="overwrite">是否覆盖远端文件</param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <param name="callback">进度回调</param> public static bool Upload(string url, string localfile, string remotePath = "", bool overwrite = true, string userName = "", string password = "", Action<long, long> callback = null) { try { string oldUrl = url; //获取文件名 string fileName = Path.GetFileName(localfile); if (!string.IsNullOrEmpty(remotePath)) { //路径连接 fileName = Path.Combine(remotePath, fileName); } //编码Url url = HttpUtility.UrlPathEncode(url + "/" + fileName);
//获取远端文件夹路径 string dir = Path.GetDirectoryName(fileName); //进行检测远端文件夹是否存在 bool check = CheckFtp(oldUrl + "/" + dir); if (!check) { //不存在进行创建 check = MaskDirectory(oldUrl, dir, userName, password); if (!check) { callback?.Invoke(-1, -1); return false; } }
//获取远端文件大小(支持断点续传) long uploadSize = GetDownloadFileSize(url); //本地文件大小 FileInfo fileInfo = new FileInfo(localfile); long totalSize = fileInfo.Length; //远端文件大小与本地文件大小对比 if (uploadSize >= totalSize) { if (overwrite) { //覆盖,重新上传 uploadSize = 0; } else { //不覆盖,停止上传 callback?.Invoke(totalSize, totalSize); return true; } }
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(url); request.Credentials = new NetworkCredential(userName, password); if (uploadSize > 0) { //断点续传 request.Method = WebRequestMethods.Ftp.AppendFile; } else { //上传 request.Method = WebRequestMethods.Ftp.UploadFile; } request.KeepAlive = false;// request.UseBinary = true; // //需上传大小 request.ContentLength = fileInfo.Length;
//读写块大小 4096B = 4k byte[] buffer = new byte[4096]; int bytesRead = 0; FileStream fileStream = fileInfo.OpenRead(); Stream stream = request.GetRequestStream();
if (uploadSize > 0) { //断点续传,将本地文件字节流读取位置设置到上次上传位置 fileStream.Seek(uploadSize, SeekOrigin.Begin); }
do { //读写,上传 bytesRead = fileStream.Read(buffer, 0, buffer.Length); uploadSize += bytesRead; stream.Write(buffer, 0, bytesRead); callback?.Invoke(uploadSize, totalSize); } while (bytesRead != 0); //上传完毕 callback?.Invoke(totalSize, totalSize);
//关闭字节流 stream.Close(); //关闭文件流 fileStream.Close(); //关闭链请求
return true; } catch (Exception ex) { callback?.Invoke(-1, -1); } return false; } 3.6 文件下载(支持断点续下)/// <summary> /// 下载文件(支持断点续下) /// </summary> /// <param name="url"></param> /// <param name="desFile">本地文件夹路径</param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static bool Download(string url, string desDir, bool overwrite = true, string userName = "", string password = "", Action<long, long> callback = null) { string fileName = Path.GetFileName(url); if (string.IsNullOrEmpty(desDir)) { //路径为空,设置文件名 desDir = fileName; } else { if (!Directory.Exists(desDir)) { //文件夹不存在,创建新文件夹 Directory.CreateDirectory(desDir); }
//路径连接 desDir = Path.Combine(desDir, fileName); }
url = HttpUtility.UrlPathEncode(url);
//下载文件大小 long downloadFileSize = GetDownloadFileSize(url, userName, password); if (downloadFileSize <= 0) { //下载文件异常 callback?.Invoke(-1, -1); return false; }
bool flag = false; long curPosition = 0; Stream stream = null; FileStream fileStream = null; //下载未完成之前存为临时文件(支持断点续下) string tmpFile = fileName + ".temp";
try { //下载文件已存在 if (File.Exists(desDir)) { var fileInfo = new FileInfo(desDir); curPosition = fileInfo.Length; if (curPosition >= downloadFileSize) { //覆盖进行删除重新下载 if(overwrite) { File.Delete(desDir); } else { callback?.Invoke(downloadFileSize, downloadFileSize); return true; } } } } catch { }
try { //临时文件存在 if (File.Exists(tmpFile)) { fileStream = File.OpenWrite(tmpFile); curPosition = fileStream.Length; //远端文件大小与临时文件大小对比 if (curPosition >= downloadFileSize) { //不覆盖 if(!overwrite) { if (fileStream != null) { fileStream.Close(); fileStream.Dispose(); } //重命名 File.Move(tmpFile, desDir); callback?.Invoke(downloadFileSize, downloadFileSize); return true; } curPosition = 0; }
callback?.Invoke(curPosition, downloadFileSize); //将本地文件字节流写入位置设置成上次下载位置 fileStream.Seek(curPosition, SeekOrigin.Current); } else { fileStream = new FileStream(tmpFile, FileMode.Create, FileAccess.Write); curPosition = 0; }
FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Credentials = new NetworkCredential(userName, password); ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile; ftpWebRequest.UseBinary = true; if (curPosition > 0) { //断点续下,将请求下载的字节流下载位置设置成上次下载位置 ftpWebRequest.ContentOffset = curPosition; }
FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse();
stream = ftpWebResponse.GetResponseStream();
byte[] buffer = new byte[4096]; int bytesRead = 0; do { //读取, 写入本地 bytesRead = stream.Read(buffer, 0, buffer.Length); curPosition += bytesRead; callback?.Invoke(curPosition, downloadFileSize); fileStream.Write(buffer, 0, bytesRead); } while (bytesRead != 0);
//下载完成 callback?.Invoke(downloadFileSize, downloadFileSize); ftpWebResponse.Close(); flag = true;
} catch (Exception e) { callback?.Invoke(-1, -1); } finally { if (stream != null) { stream.Close(); stream.Dispose(); } if (fileStream != null) { fileStream.Flush(); fileStream.Close(); fileStream.Dispose(); } if (flag) { File.Move(tmpFile, desDir); } }
return flag; } 3.7 文件删除/// <summary> /// 删除文件 /// </summary> /// <param name="url"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static bool Delete(string url, string userName = "", string password = "") { try { url = HttpUtility.UrlPathEncode(url); FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Method = WebRequestMethods.Ftp.DeleteFile; ftpWebRequest.KeepAlive = false; ftpWebRequest.Credentials = new NetworkCredential(userName, password);
FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse(); Stream stream = ftpWebResponse.GetResponseStream();
stream.Close(); ftpWebResponse.Close(); return true; } catch (Exception ex) { } return false; } 3.8 重命名/// <summary> /// 重命名 /// </summary> /// <param name="url"></param> /// <param name="newName">新名称,涉及到多级文件夹(未实现)</param> /// <param name="userName">账号</param> /// <param name="password">密码</param> /// <returns></returns> public static bool Rename(string url, string newName, string userName = "", string password = "") { try { url = HttpUtility.UrlPathEncode(url); FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(url); ftpWebRequest.Method = WebRequestMethods.Ftp.Rename; ftpWebRequest.RenameTo = newName; ftpWebRequest.KeepAlive = false; ftpWebRequest.Credentials = new NetworkCredential(userName, password);
FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse(); Stream stream = ftpWebResponse.GetResponseStream();
stream.Close(); ftpWebResponse.Close(); return true; } catch (Exception ex) { } return false; } 3.9 移动文件/// <summary> /// 移动文件夹 /// </summary> /// <param name="url"></param> /// <param name="newName"></param> /// <param name="userName">账号</param> /// <param name="password">密码</param> public static void MoveFile(string url, string newName, string userName = "", string password = "") { Rename(url, newName, userName, password); } 该文章在 2024/1/12 16:15:48 编辑过 |
关键字查询
相关文章
正在查询... |