-
【问题来源】【必填】南网电网【问题简要】【必填】屏幕共享必须要与openeye建立websocket链接的前提下通过方法进行触发吗,能否直接通过openeye进行共享【问题类别】【必填】CC-Gateway【AICC解决方案版本】【必填】AICC 24.200.0【期望解决时间】【选填】尽快【问题现象描述】【必填】屏幕共享必须要与openeye建立websocket链接的前提下通过方法进行触发吗,能否直接通过openeye进行共享【日志或错误截图】【可选】无【附件】【可选】无
-
【问题来源】【必填】南网电网【问题简要】【必填】通过openeye实现的视频坐席,能否实现将图片推送到来电用户的手机端进行展示【问题类别】【必填】CC-Gateway【AICC解决方案版本】【必填】AICC 24.200.0【期望解决时间】【选填】尽快【问题现象描述】【必填】当用户咨询电费账单时,客服代表点击"动态图片推送"后,弹出场景列表,选择相关场景后,将电费账单信息以图片形式在用户手机端展示。【日志或错误截图】【可选】无【附件】【可选】无
-
ArrayList概述ArrayList是Java中的一个重要组件,属于java.util包,是一种基于数组的列表(List)实现,能够以动态的方式存储对象。与传统数组不同的是,ArrayList允许在运行时动态调整自身的大小,这使得它在处理未知数量元素时非常有用。ArrayList的基本用法添加元素向ArrayList中添加元素是通过add()方法实现的。例如,可以将一个整数添加到ArrayList中:ArrayList<Integer> numbers = new ArrayList<>();numbers.add(12);访问元素可以通过get()方法按索引访问ArrayList中的元素:int firstElement = numbers.get(0);修改元素使用set()方法可以修改指定索引位置的元素:numbers.set(0, 13); // 将索引0的元素修改为13删除元素删除元素可以使用remove()方法,也可以使用clear()方法清空整个ArrayList:numbers.remove(0); // 删除索引为0的元素numbers.clear(); // 清空ArrayListArrayList的特点动态数组:ArrayList是基于数组的,但它允许在运行时动态增加或删除元素,而不需要重新分配数组。线程不安全:ArrayList不是线程安全的,这意味着在多线程环境中,需要采取额外的同步措施来保护ArrayList。随机访问:ArrayList支持快速的随机访问,即O(1)时间复杂度。插入和删除操作:虽然在数组末尾添加或删除元素很快(O(1)),但在数组中间进行插入或删除操作则较慢,时间复杂度为O(n)。扩容机制:当ArrayList达到容量限制时,会自动进行扩容,这个过程可能涉及复制原有数据到一个更大的数组中,这可能会带来性能开销。ArrayList的应用场景ArrayList适用于以下场景:当需要存储大量数据且数量未知时。当需要频繁进行插入和删除操作时。当需要随机访问列表中的元素时。ArrayList与其他数据结构的比较与Arrays比较:与固定大小的数组相比,ArrayList提供了动态调整大小的能力,更适合数据量不确定的情况。与LinkedList比较:LinkedList在插入和删除操作上通常更快,尤其是在列表中间操作时,但随机访问元素的速度较慢。相比之下,ArrayList在随机访问上较快,但在插入和删除操作上较慢。总结ArrayList是Java中一种常用的动态数组实现,它提供了丰富的方法来方便地进行列表操作。了解它的特点和使用场景对于有效地利用ArrayList非常重要。在实际开发中,应根据具体需求选择最合适的数据结构。
-
XLSX.SSF.format 是 Apache POI 库中用于处理 Excel 文件(特别是 .xlsx 格式)时,用于格式化单元格数据的一个功能。Apache POI 是一个流行的 Java 库,它提供了对 Microsoft Office 格式文件的读写能力,包括 Excel、Word 等。在 Excel 文件的处理中,XLSX.SSF.format 允许开发者根据预定义的格式字符串或自定义的格式字符串来设置单元格的显示格式。基本用法在 Apache POI 中,XSSFDataFormat 类是处理单元格数据格式的关键类。你可以通过 XSSFWorkbook 对象获取到一个 XSSFDataFormat 实例,然后使用它来获取或创建格式字符串。一旦你有了格式字符串,就可以将其应用到 XSSFCellStyle 对象上,进而将该样式应用到单元格上。// 假设 workbook 是已经创建的 XSSFWorkbook 对象 XSSFDataFormat format = workbook.createDataFormat(); short formatIndex = format.getFormat("#,##0.00"); // 获取或创建格式为“#,##0.00”的索引 // 接下来,你可以将这个格式索引设置到单元格样式上 XSSFCellStyle cellStyle = workbook.createCellStyle(); cellStyle.setDataFormat(formatIndex); // 最后,将这个样式应用到单元格上 XSSFCell cell = ...; // 假设这是已经创建的单元格 cell.setCellStyle(cellStyle);格式字符串格式字符串遵循 Excel 的数字格式代码规则,这些规则允许你定义如何显示数字、日期、时间、货币等。例如:#,##0.00:表示带有千位分隔符和两位小数的数字。yyyy-mm-dd:表示日期格式为年-月-日。0.00%:表示百分比,保留两位小数。注意事项当使用 XSSFDataFormat.getFormat(String formatString) 方法时,如果传入的 formatString 已经存在于工作簿的格式列表中,则该方法会返回该格式的索引;如果不存在,则会创建一个新的格式并返回其索引。单元格的显示格式和它的实际值是分开的。即使你改变了单元格的显示格式,单元格的实际值(存储在 XSSFCell 对象中的值)也不会改变。在处理大量数据时,应谨慎使用自定义格式,因为每个自定义格式都会增加工作簿的大小。结论XLSX.SSF.format(在 Apache POI 的上下文中更准确地说是 XSSFDataFormat 和相关的格式字符串)是处理 Excel 文件中单元格数据格式的强大工具。通过它,开发者可以灵活地定义单元格的显示方式,以满足不同的数据处理和展示需求。
-
包含功能为: 1、向Ftp服务器上传文件 2、从Ftp服务器下载特定文件 3、从Ftp某个文件夹里面下载所有文件 4、远程在FTP服务器指定位置创建文件夹 5、查看FTP服务器指定目录内所有文件名 解决了FTP上传/下载文件时,文件名有中文,有特殊字符时无法上传/下载的问题。 写在前面 可以直接运行的,包含上述全部功能的代码已经上传到github上了,下载文件,配置好自己的环境即可直接使用。代码中包含详细注释以及使用方式。 github链接:https://github.com/DylanYh2/FTPClient_libcurl.git libcurl库windows下编译配置 windows系统编译libcurl库,并在visual studio2019/2022使用(win10,win11通用) libcurl c++常用操作 libcurl c++常用操作 libcurl库实现FTP远程文件操作 头文件 #pragma once #include<iostream> #include<curl/curl.h> #include<string> #include<vector> using namespace std; class FtpManage { public: FtpManage(); FtpManage(const string user, const string password, const string id); ~FtpManage(); /* *@Upload: 向Ftp服务器上传文件 * @localFilePath:所上传的文件(精确到文件名),如"D:/ggbond/123.jpg" * @remoteDirectory:上传至Ftp的目录,如"/shjr/" * @remark:将123.jpg上传到Ftp服务器的"/shjr/"目录下, */ bool Upload(const char* localFilePath, const char* remoteDirectory); /* * @Download:从Ftp服务器下载特定文件 * @remoteFilePath:所下载的文件(精确到文件名)如"/shjr/333.jpg" * @localDirectory:保存至本地目录,如"D:/ggbond/" * @remark:将FTp服务器/shjr目录下的333.jpg下载到本地D:/ggbond目录 */ bool DownloadFile(const char* remoteFilePath, const char* localDirectory); /* * @DownloadAllFiles:从Ftp某个文件夹里面下载所有文件 * @remoteFilePath:所下载的文件夹名称,如"/shjr/" * @localDirectory:保存至本地目录,如"D:/ggbond/" * @remark:将FTp服务器/shjr/目录里面下载所有文件到本地D:/ggbond/目录 */ bool DownloadAllFiles(const char* remoteFilePath, const char* localDirectory); /* * @Createdir:创建文件夹 * @directoryname:文件夹名称,可包含上级目录名,要以“/”结尾以表示目录 * 比如:"/ggbond/" */ bool Createdir(const char* directoryname); /* * @GetFilesName:提供获取FTP文件夹内所有文件名的接口 * @filepath:文件夹名称,可包含上级目录名,要以“/”结尾以表示目录 * 比如:"/ggbond/" */ const std::vector<std::string>& GetFilesName(const string filepath); private: /* * @SetURL:初始化URL */ void SetURL(); /* * @UrlEncode:把含有特殊符号的文件名进行URL编码 * @value:文件名 * @"kunkunboy## 123"这种形式是无法传入curl的,需要转换一下 */ std::string UrlEncode(const std::string& value); /* * @GEtFileNameFromPath:从路径中提取文件名并返回 * @filePath:文件完整路径 * @"D:/ggbond/123.jpg"->123.jpg */ std::string GetFileNameFromPath(const std::string& filePath); /* * @GetfilenameFromftp:获得FTP服务器上某个文件夹内所有文件名,如果文件夹内既有文件又有文件夹,则只会显示文件 * @directoryname:文件夹名称,可包含上级目录名,要以“/”结尾以表示目录 */ bool GetfilenameFromftp(const string directoryname); private: std::string Ftp_ip; //Ftp服务器地址 std::string User, Password; //登录用户名及密码 std::string _URL; std::vector<std::string> fNs; //用于记录全部文件名 CURL* curl; }; 向Ftp服务器上传文件 核心代码为: /* *@Upload: 向Ftp服务器上传文件 * @localFilePath:所上传的文件(精确到文件名),如"D:/ggbond/123.jpg" * @remoteDirectory:上传至Ftp的目录,如"/shjr/" * @remark:将123.jpg上传到Ftp服务器的"/shjr/"目录下, */ bool Upload(const char* localFilePath, const char* remoteDirectory); { SetURL(); _URL = Ftp_ip + remoteDirectory+ GetFileNameFromPath(localFilePath); curl_easy_setopt(curl, CURLOPT_URL, _URL.c_str()); // 设置访问的FTP地址 if (curl) { FILE* fp = fopen(localFilePath, "rb"); curl_off_t fsize = 0; if (fp) { fseek(fp, 0, SEEK_END); fsize = ftell(fp); // 获取文件大小 fseek(fp, 0, SEEK_SET); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); // 指定为上传文件模式 curl_easy_setopt(curl, CURLOPT_READDATA, fp); // 指定上传的文件是哪个 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, fsize);// 指定上传的文件大小 CURLcode res = curl_easy_perform(curl); // 开始上传 if (res != CURLE_OK) { std::cout << "localFilePath: " << localFilePath << " upload failed!" << curl_easy_strerror(res) << std::endl; curl_easy_cleanup(curl); fclose(fp); return false; } else { std::cout << "localFilePath: " << localFilePath << " upload successfully!" << std::endl; } fclose(fp); } else { std::cout << "file: " << localFilePath << " open failed!" << std::endl; curl_easy_cleanup(curl); return false; } } curl_easy_cleanup(curl); return true; } 从Ftp服务器下载指定文件 核心代码为: /* * @Download:从Ftp服务器下载特定文件 * @remoteFilePath:所下载的文件(精确到文件名)如"/shjr/333.jpg" * @localDirectory:保存至本地目录,如"D:/ggbond/" * @remark:将FTp服务器/shjr目录下的333.jpg下载到本地D:/ggbond目录 */ bool FtpManage::DownloadFile(const char* remoteFilePath, const char* localDirectory) { SetURL(); _URL = Ftp_ip + UrlEncode(remoteFilePath); curl_easy_setopt(curl, CURLOPT_URL, _URL.c_str()); // 设置请求的URL if (curl) { FILE* fp = fopen((localDirectory + GetFileNameFromPath(remoteFilePath)).c_str(), "wb"); if (fp) { // 设置文件写入地址 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); // 执行任务 CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cout << "DownLoad file:" << remoteFilePath << " failed! " << curl_easy_strerror(res) << std::endl; fclose(fp); curl_easy_cleanup(curl); return false; } else { std::cout << "DownLoad file:" << remoteFilePath << " successfully!" << std::endl; fclose(fp); } } else { std::cout << "file open failed!" << std::endl; curl_easy_cleanup(curl); // 清除curl return false; } } curl_easy_cleanup(curl); return true; } 从Ftp某个文件夹里面下载所有文件 /* * @DownloadAllFiles:从Ftp某个文件夹里面下载所有文件 * @remoteFilePath:所下载的文件夹名称,如"/shjr/" * @localDirectory:保存至本地目录,如"D:/ggbond/" * @remark:将FTp服务器/shjr/目录里面下载所有文件到本地D:/ggbond/目录 */ bool FtpManage::DownloadAllFiles(const char* remoteFilePath, const char* localDirectory) { if (GetfilenameFromftp(remoteFilePath)) { for (const auto& fns : fNs) { std::string filename = remoteFilePath + fns; bool res = DownloadFile(filename.c_str(), localDirectory); if (res) continue; else { return false; } } } return true; } 远程在FTP上创建文件夹 /* * @Createdir:创建文件夹 * @directoryname:文件夹名称,可包含上级目录名,要以“/”结尾以表示目录 * 比如:"/ggbond/" */ bool FtpManage::Createdir(const char* directoryname) { if (directoryname == nullptr) { std::cout << "directoryname is NULL!" << std::endl; return false; } SetURL(); _URL = Ftp_ip + UrlEncode(directoryname); curl_easy_setopt(curl, CURLOPT_URL, _URL.c_str()); // 指定url curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); //如果目录不存在则创建一个 CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cout << "Directory:" << directoryname << "create failed!" << curl_easy_strerror(res) << std::endl; curl_easy_cleanup(curl); // 清理curl return false; } else { std::cout << "Create directory:" << directoryname << " successfully!" << std::endl; } curl_easy_cleanup(curl); return true; } 获取FTP文件夹内所有文件名 /* * @GetFilesName:提供获取FTP文件夹内所有文件名的接口 * @filepath:文件夹名称,可包含上级目录名,要以“/”结尾以表示目录 * 比如:"/ggbond/" */ //接收消息回调函数 size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) { size_t totalSize = size * nmemb; output->append(static_cast<char*>(contents), totalSize); return totalSize; } // 获取ftp某个文件夹内文件名 bool FtpManage::GetfilenameFromftp(const std::string filePath) { SetURL(); std::string path = Ftp_ip + UrlEncode(filePath); std::string fileName; // 文件名列表保存位置 if (curl) { curl_easy_setopt(curl, CURLOPT_URL, path.c_str()); // 设置访问URL curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); // 设置只返回文件 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileName); // 设置只获取文件名列表 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); // 设置get的回调函数 if (curl_easy_perform(curl) == CURLE_OK) //执行任务 { fNs.clear(); size_t startPos = 0, endPos = 0; while ((endPos = fileName.find('\n', startPos)) != std::string::npos ) { std::string name = fileName.substr(startPos, endPos - startPos-1); fNs.emplace_back(name); startPos = endPos + 1; } } } else { return false; } curl_easy_cleanup(curl); return true; } // 获取FTP文件夹内所有文件名的接口函数 const std::vector<std::string>& FtpManage::GetFilesName(const string filepath) { if (GetfilenameFromftp(filepath)) { return fNs; } else { return std::vector<std::string>(); } } 解决文件名中空格、特殊字符无法出现错误 // 对文件名进行URL编码,否则文件名中有空格,特殊符合(#^...)会出现URL错误 std::string FtpManage::UrlEncode(const std::string &value) { CURL* curl = curl_easy_init(); if (!curl) return ""; char* output = curl_easy_escape(curl, value.c_str(), value.length()); if (output) { std::string encoded(output); curl_free(output); curl_easy_cleanup(curl); return encoded; } curl_easy_cleanup(curl); return ""; } 其他相关函数 // 把带有路径的文件转换为文件名 D:/ggbond/123.jpg->123.jpg std::string FtpManage::GetFileNameFromPath(const std::string& filePath) { if (filePath == "") return filePath; //去除路径最后的空格 string retPath; size_t lastBlank = filePath.find_last_not_of(' '); if (lastBlank != std::string::npos) { retPath = filePath.substr(0, lastBlank+1); } else { return ""; } size_t lastSlashPos = retPath.find_last_of("/\\"); if (lastSlashPos != std::string::npos) { return retPath.substr(lastSlashPos + 1); } else { // 如果没有找到斜杠或反斜杠,整个路径就是文件名 return retPath; } } ———————————————— 原文链接:https://blog.csdn.net/yh_secret/article/details/140661525
-
FTP(File Transfer Protocol,文件传输协议)是一种用于在计算机网络上进行文件传输的标准协议。它定义了客户端和服务器之间的通信规则,使得用户可以通过网络上传和下载文件,以下分别是文件的下载以及上的过程。 1. 文件下载的过程 ① 建立连接 // 创建了一个名为ftpClient的FTP客户端对象 FTPClient ftpClient = new FTPClient(); // 指定文件下载的路径,通过ftp访问指定目录并下载文件 try (FileOutputStream out = new FileOutputStream("下载路径" + System.currentTimeMillis())){ // 连接ftp服务器(ftp默认的端口号为21)并验证用户名、密码 ftpClient.connect("ip地址",21); ftpClient.login("用户名", "密码"); } ② 切换至个人目录 boolean isChange = ftpClient.changeWorkingDirectory("个人目录名"); System.out.println("目录切换成功了吗?" + isChange); ③ 下载指定文件 // 设置文件的类型 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 下载文件,并确定结果 boolean isRetrieve = ftpClient.retrieveFile("待下载的文件名", out); 2. 文件上传过程 ① 连接ftp服务器并验证用户名、密码 无论是上传文件或是下载文件,第一部都需要先建立连接,因此,第一步的实现方法是相同的,不过,由于下载文件时是将读取到的文件存放至本地文件,因此采用的是文件输出流,但在文件上传过程中,是将本地文件读取至程序中并上传,因此需要定义的是文件输入流,以便读取本地文件并上传。 ② 切换目录至上传文件处 // 通过changeWorkingDirectory()方法切换目录并判断是否切换成功 boolean isChange = ftpClient.changeWorkingDirectory("目标目录名"); // 获取当前目录中的所有文件 FTPFile[] ftpFileList = ftpClient.listFiles(); // 如若没有你想上传的目录也可以自行建立一个目录 // 创建个人目录 ftpClient.makeDirectory("创建的目录名"); // 切换至新建目录 ftpClient.changeWorkingDirectory("创建的目录"); ③ 上传文件并存放 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 存文件至FTP boolean isStore = ftpClient.storeFile(System.currentTimeMillis(), 文件输入流); ———————————————— 原文链接:https://blog.csdn.net/qq_72172339/article/details/131645398
-
public void downloadFileStream(HttpServletResponse response, String path, String fileName) { OutputStream outputStream = null; FTPClient ftpClient = getFtpClient(); InputStream in = null; BufferedInputStream bis = null; try { int index = path.indexOf("/"); int index1 = path.indexOf("/", index + 2); //文件路径 去除掉ftp地址 String filePath = path.substring(index1) ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置文件ContentType类型,这样设置,会自动判断下载文件类型 response.setContentType("application/x-msdownload"); // 设置文件头:最后一个参数是设置下载的文件名并编码为UTF-8 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); // 此句代码适用Linux的FTP服务器 String newPath = new String(fileName.getBytes("GBK"), StandardCharsets.ISO_8859_1); ftpClient.enterLocalPassiveMode(); // 设置被动模式,开通一个端口来传输数据 boolean result = existFile(filePath, ftpClient); if (result) { ftpClient.changeWorkingDirectory(path); in = ftpClient.retrieveFileStream(newPath); bis = new BufferedInputStream(in); outputStream = response.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while ((len = bis.read(buf)) > 0) { outputStream.write(buf, 0, len); } outputStream.flush(); } } catch (IOException e) { log.error("下载文件出错!", (Object) e.getStackTrace()); } finally { releaseFtpClient(ftpClient); if (null != outputStream) { try { outputStream.close(); } catch (IOException e) { log.error("关闭输出流出错!", (Object) e.getStackTrace()); } } if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); //需要注意,在使用ftpClient.retrieveFileStream,一定要加completePendingCommand() //调用这个接口后,一定要手动close掉返回的InputStream,然后再调用completePendingCommand方法,若不是按照这个顺序,则会导致后面对FTPClient的操作都失败 ftpClient.completePendingCommand(); } catch (IOException e) { e.printStackTrace(); } } } } ———————————————— 原文链接:https://blog.csdn.net/weixin_40388298/article/details/119907061
-
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; public class FtpFileTransferWithOriginalName { public static void main(String[] args) { String server = "your_server"; int port = 21; String user = "your_user"; String pass = "your_password"; // 下载文件 downloadFile(server, port, user, pass, "/remote_path/file.txt", "/local_path"); // 上传文件 uploadFile(server, port, user, pass, "/local_path/file.txt", "/remote_path"); } public static void downloadFile(String server, int port, String user, String pass, String remotePath, String localPath) { FTPClient ftpClient = new FTPClient(); try { ftpClient.connect(server, port); ftpClient.login(user, pass); ftpClient.enterLocalPassiveMode(); FTPFile[] files = ftpClient.listFiles(remotePath); if (files.length > 0) { FTPFile file = files[0]; String originalFileName = file.getName(); // 获取原文件名 File localFile = new File(localPath + File.separator + originalFileName); // 使用原文件名创建本地文件 OutputStream outputStream = new FileOutputStream(localFile); ftpClient.retrieveFile(remotePath, outputStream); outputStream.close(); } ftpClient.logout(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (ftpClient.isConnected()) { ftpClient.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } } public static void uploadFile(String server, int port, String user, String pass, String localPath, String remotePath) { FTPClient ftpClient = new FTPClient(); try { ftpClient.connect(server, port); ftpClient.login(user, pass); ftpClient.enterLocalPassiveMode(); File localFile = new File(localPath); String originalFileName = localFile.getName(); // 获取原文件名 // 检查服务器端是否存在同名文件,如果存在则添加后缀避免冲突 boolean fileExists = checkFileExists(ftpClient, remotePath + File.separator + originalFileName); if (fileExists) { originalFileName = addSuffixToFileName(originalFileName); } ftpClient.storeFile(remotePath + File.separator + originalFileName, new FileInputStream(localFile)); ftpClient.logout(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (ftpClient.isConnected()) { ftpClient.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } } // 检查服务器端指定路径是否存在文件 public static boolean checkFileExists(FTPClient ftpClient, String filePath) throws IOException { FTPFile[] files = ftpClient.listFiles(filePath); return files.length > 0; } // 给文件名添加后缀以避免冲突 public static String addSuffixToFileName(String fileName) { return fileName + "_new"; } } ———————————————— 原文链接:https://blog.csdn.net/hongyuxiongji/article/details/140848594
-
一、前端 1.首先创建下载文件按钮 <template slot-scope="scope"> <div class="Style_center"> <el-button @click="downloadFile(scope.row)" type="text" >下载文件</el-button> </div> </template> 2.其次编写手动触发事件 downloadFile(row){ this.axios.post("/Zlhzjbxxb/downloadFile", {wjdz:row.wjdz, wjmc:row.wjmc},{ headers: { //解决后端接收时多了一个 = 'Content-Type': 'application/json' } }).then(res => { this.$message.success("成功下载至桌面"); }) } wjdz和wjmc是要传给后端的值。后端获取到文件的FTP路径的时候,路径末尾会莫名的多一个等于(=)的符号,反正我的是出现了,把headers加上就完美解决了 二、后端 结尾处贴附后端全码 1.用Map来接收前端传过来的数据 public void downloadFile(@RequestBody Map<String,String> map) throws UnsupportedEncodingException { String wjdz = map.get("wjdz"); String wjmc = map.get("wjmc"); } 2.获取的文件路径,比如C:\Users\Administrator\Desktop,中间的 \ 符号会被转义,所以需要转义回来,其它符号的转义可以百度一下哦。 //解决文件名中间的符号被转义(如“/”被转义成%2F) wjdz = wjdz.replaceAll("%(?![0-9a-fA-F]{2})", "%2F"); String wjdzStr = URLDecoder.decode(wjdz, "UTF-8"); 3.在上传FTP文件的时候,为了防止重复的文件名在FTP服务器里出现,于是给每一个文件都设置了不同的文件编号,格式为xxx/2021-05-09/**************(*是uuid创建拼接在后面的),在FTP服务器里面下载文件的话需要找到具体的目录,然后再去下载具体的文件。接下来开始获取FTP文件的名称以及目录名 //获取第一个“/”的位置 int index = wjdzStr.indexOf("/"); //获取第二个 “/” 的位置 index = wjdzStr.indexOf("/", index + 1); //获取第二个 “/” 的位置后面的字符串 String result = wjdzStr.substring(index + 1); //获取第二个 “/” 的位置之前的字符串 String menuDz = wjdzStr.substring(0,index + 1); 通过以上方式来获取文件的目录和文件名称,result就是需要下载文件的名称,menuDz就是文件所在的FTP服务器里面的目录 4.接下来就是设置文件的保存地址了 FileOutputStream out = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\" + wjmc ) 这里我是给设置到了桌面,后面的wjmc是该文件的中文名称,总不能给用户展示文件的路径吧...... 5.开始连接FTP服务器并且登录 FTPClient ftpClient = new FTPClient(); ftpClient.connect(hostName, port);//连接 ftpClient.login(userName, password);//登陆 这里的hostname是自己的IP地址,port是端口号(默认21),userName是用户名,password就是密码了,如果在yml文件里面封装的有,便可以直接调用,没有就自己手动填上去也是一样的 6.登上去之后便开始下载文件了,首先找到文件目录,然后再去下载 ftpClient.changeWorkingDirectory(menuDz);//切换目录 //下载文件( 获取FTP服务器指定目录的文件) //参数result,服务器指定文件 //参数out,本地输出流(负责下载后写入) ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE); ftpClient.retrieveFile(result,out); ftpClient.setFileType这个就是用来配置文件传输形式的,默认ASCII,我们一般都是配置用二进制形式传送 7.最后最后就是退出登录和关闭连接了 ftpClient.logout();// 退出登录 ftpClient.disconnect();// 断开连接 8.接下来就是后端的全码了 @PostMapping(value = "/downloadFile") @ResponseBody public void downloadFile(@RequestBody Map<String,String> map) throws UnsupportedEncodingException { String wjdz = map.get("wjdz"); String wjmc = map.get("wjmc"); //解决文件名中间的符号被转义(如“/”被转义成%2F) wjdz = wjdz.replaceAll("%(?![0-9a-fA-F]{2})", "%2F"); String wjdzStr = URLDecoder.decode(wjdz, "UTF-8"); FTPClient ftpClient = new FTPClient(); int index = wjdzStr.indexOf("/"); //获取第一个“/”的位置 index = wjdzStr.indexOf("/", index + 1);//获取第二个 “/” 的位置 String result = wjdzStr.substring(index + 1);//获取第二个 “/” 的位置后面的字符串 String menuDz = wjdzStr.substring(0,index + 1);//获取第二个 “/” 的位置之前的字符串 try (FileOutputStream out = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\" + wjmc )) { FtpUtil ftpUtil = new FtpUtil(); ftpClient.connect(ftpUtil.hostName, ftpUtil.port);//连接 ftpClient.login(ftpUtil.userName, ftpUtil.password);//登陆 ftpClient.changeWorkingDirectory(menuDz);//切换目录 //下载文件( 获取FTP服务器指定目录的文件) //参数result,服务器指定文件 //参数out,本地输出流(负责下载后写入) ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE); ftpClient.retrieveFile(result,out); } catch (SocketException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { ftpClient.logout();// 退出登录 ftpClient.disconnect();// 断开连接 } catch (IOException e) { e.printStackTrace(); } } } 记录这些方便自己的同时也想能帮助一下和我遇到同样困惑的人,有什么不足或者不对的地方还望大佬们指出 ———————————————— 原文链接:https://blog.csdn.net/glacierW/article/details/130581947
-
一、FTP介绍 FTP是File Transfer Protocol(文件传输协议)的英文简称,即文件协议。用于Internet上的控制文件的双向传输。同时,它是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有的应用程序都遵守同一种协议以传输文件。在FTP的使用中,用户经常遇到两个概念:下载(Download)和上次(Upload)。下载文件就是从远程主机拷贝文件至自己的计算机上;删除文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向远程主机上传、下载文件(摘自百度百科)。 二、准备工作 1、在服务器安装FTP服务 FTP服务需要下FileZilla_Server服务安装程序,大家可以在网上搜索,也可以通过我的资源下载 点击下载 2、编写Java连接FTP源码 大家也可以通过CSDN资源下载我的源码 点击下载 三、实现步骤 1、编写FTP-Config.properties配置属性文件 FTP_IP=localhost FTP_PORT=21 FTP_USER=wangjunwei FTP_PASSWORD=wangjunwei FTP_PATH=/FTP FTP_DRIVELETTER=E: 2、编写FTPUtil读取FTP配置属性文件 /** * FTP服务地址 */ private static String FTP_IP; /** * FTP端口号 */ private static Integer FTP_PORT; /** * FTP用户名 */ private static String FTP_USER; /** * FTP密码 */ private static String FTP_PASSWORD; /** * FTP根路径 */ private static String FTP_PATH; /** * 映射盘符 */ private static String FTP_DRIVELETTER; static{ try { Properties properties = new Properties(); InputStream inputStream = FtpUtil.class.getResourceAsStream("/FTP-Config.properties"); properties.load(inputStream); FTP_IP = properties.getProperty("FTP_IP"); FTP_PORT = Integer.valueOf(properties.getProperty("FTP_PORT")); FTP_USER = properties.getProperty("FTP_USER"); FTP_PASSWORD = properties.getProperty("FTP_PASSWORD"); FTP_PATH = properties.getProperty("FTP_PATH"); FTP_DRIVELETTER = properties.getProperty("FTP_DRIVELETTER"); } catch (IOException e) { e.printStackTrace(); } } 3、连接(登录)FTP服务端获取授权 private static FTPClient ftpClient; public static FTPClient connectionFTPServer() { ftpClient = new FTPClient(); try { ftpClient.connect(FtpUtil.getFTP_IP(), FtpUtil.getFTP_PORT()); ftpClient.login(FtpUtil.getFTP_USER(), FtpUtil.getFTP_PASSWORD()); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { logger.info("==============未连接到FTP,用户名或密码错误================="); ftpClient.disconnect(); } else { logger.info("==============连接到FTP成功================="); } } catch (SocketException e) { e.printStackTrace(); logger.info("==============FTP的IP地址错误=============="); } catch (IOException e) { e.printStackTrace(); logger.info("==============FTP的端口错误=============="); } return ftpClient; } 4、编写文件上传、下载相关方法 /** * 切换到父目录 * * @return 切换结果 true:成功, false:失败 */ private static boolean changeToParentDir() { if (!ftpClient.isConnected()) { return false; } try { return ftpClient.changeToParentDirectory(); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 改变当前目录到指定目录 * * @param dir * 目的目录 * @return 切换结果 true:成功,false:失败 */ private static boolean cd(String dir) { if (!ftpClient.isConnected()) { return false; } try { return ftpClient.changeWorkingDirectory(dir); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 获取目录下所有的文件名称 * * @param filePath * 指定的目录 * @return 文件列表,或者null */ private static FTPFile[] getFileList(String filePath) { if (!ftpClient.isConnected()) { return null; } try { return ftpClient.listFiles(filePath); } catch (IOException e) { e.printStackTrace(); return null; } } /** * 切换工作目录 * * @param ftpPath * 目的目录 * @return 切换结果 */ public static boolean changeDir(String ftpPath) { if (!ftpClient.isConnected()) { return false; } try { // 将路径中的斜杠统一 char[] chars = ftpPath.toCharArray(); StringBuffer sbStr = new StringBuffer(256); for (int i = 0; i < chars.length; i++) { if ('\\' == chars[i]) { sbStr.append('/'); } else { sbStr.append(chars[i]); } } ftpPath = sbStr.toString(); if (ftpPath.indexOf('/') == -1) { // 只有一层目录 ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(), "iso-8859-1")); } else { // 多层目录循环创建 String[] paths = ftpPath.split("/"); for (int i = 0; i < paths.length; i++) { ftpClient.changeWorkingDirectory(new String(paths[i].getBytes(), "iso-8859-1")); } } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 循环创建目录,并且创建完目录后,设置工作目录为当前创建的目录下 * * @param ftpPath * 需要创建的目录 * @return */ public static boolean mkDir(String ftpPath) { if (!ftpClient.isConnected()) { return false; } try { // 将路径中的斜杠统一 char[] chars = ftpPath.toCharArray(); StringBuffer sbStr = new StringBuffer(256); for (int i = 0; i < chars.length; i++) { if ('\\' == chars[i]) { sbStr.append('/'); } else { sbStr.append(chars[i]); } } ftpPath = sbStr.toString(); if (ftpPath.indexOf('/') == -1) { // 只有一层目录 ftpClient.makeDirectory(new String(ftpPath.getBytes(), "iso-8859-1")); ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(), "iso-8859-1")); } else { // 多层目录循环创建 String[] paths = ftpPath.split("/"); for (int i = 0; i < paths.length; i++) { ftpClient.makeDirectory(new String(paths[i].getBytes(), "iso-8859-1")); ftpClient.changeWorkingDirectory(new String(paths[i].getBytes(), "iso-8859-1")); } } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 上传单个文件 * * @param inputStream * 单个文件流对象 * @param newFileName * 新文件名 * @param folder * 自定义保存的文件夹 * @return 上传结果 */ public static boolean uploadSingleAttachment(File file, String newFileName, String folder) { FtpUtil.connectionFTPServer(); if (!ftpClient.isConnected()) { logger.info("==============FTP服务已断开=============="); return false; } boolean result = false; if (ftpClient != null) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); if(StringUtils.isNotEmpty(folder)){ FtpUtil.mkDir(folder); } ftpClient.setBufferSize(100000); ftpClient.setControlEncoding("utf-8"); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); result = ftpClient.storeFile(new String(newFileName.getBytes(), "iso-8859-1"), fileInputStream); } catch (Exception e) { FtpUtil.close(); e.printStackTrace(); return false; } finally { try { if (ftpClient.isConnected()) { FtpUtil.close(); } fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * 上传多个文件 * * @param inputStreams * 多文件流对象数组 * @param newFileNames * 多文件名数组(与流对象数组一一对应) * @param folder * 自定义保存的文件夹 * @return 上传结果 */ public static String[] uploadBatchAttachment(File[] files , String[] newFileNames, String folder) { String[] filesSaveUrls = new String[files.length]; FtpUtil.connectionFTPServer(); if (!ftpClient.isConnected()) { logger.info("==============FTP服务已断开=============="); return null; } if (ftpClient != null) { FileInputStream fileInputStream = null; try { if(StringUtils.isNotEmpty(folder)){ FtpUtil.mkDir(folder); } for (int i = 0; i < files.length; i++) { filesSaveUrls[i] = FtpUtil.FTP_PATH; fileInputStream = new FileInputStream(files[i]); if(StringUtils.isNotEmpty(folder)){ filesSaveUrls[i] += "/"+folder; } ftpClient.setBufferSize(100000); ftpClient.setControlEncoding("utf-8"); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.storeFile(new String(newFileNames[i].getBytes(), "iso-8859-1"), fileInputStream); filesSaveUrls[i] += "/"+newFileNames[i]; } } catch (Exception e) { FtpUtil.close(); e.printStackTrace(); return null; } finally { try { if (ftpClient.isConnected()) { FtpUtil.close(); } fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return filesSaveUrls; } /** * 上传单个文件 * * @param inputStreams * 多文件流对象数组 * @param newFileNames * 多文件名数组(与流对象数组一一对应) * @param folder * 自定义保存的文件夹 * @return 上传结果 */ public static String uploadSingleAttachment(MultipartFile multipartFile, String newFileName, String folder) { String filesSaveUrl = null; FtpUtil.connectionFTPServer(); if (!ftpClient.isConnected()) { logger.info("==============FTP服务已断开=============="); return null; } if (ftpClient != null) { try { if(StringUtils.isNotEmpty(folder)){ FtpUtil.mkDir(folder); } filesSaveUrl = FtpUtil.FTP_PATH; if(StringUtils.isNotEmpty(folder)){ filesSaveUrl += "/"+folder; } ftpClient.setBufferSize(100000); ftpClient.setControlEncoding("utf-8"); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.storeFile(new String(newFileName.getBytes(), "iso-8859-1"), multipartFile.getInputStream()); filesSaveUrl += "/"+newFileName; } catch (Exception e) { FtpUtil.close(); e.printStackTrace(); return null; } finally { if (ftpClient.isConnected()) { FtpUtil.close(); } } } return filesSaveUrl; } /** * 上传多个文件 * * @param inputStreams * 多文件流对象数组 * @param newFileNames * 多文件名数组(与流对象数组一一对应) * @param folder * 自定义保存的文件夹 * @return 上传结果 */ public static String[] uploadBatchAttachment(MultipartFile[] multipartFiles , String[] newFileNames, String folder) { String[] filesSaveUrls = new String[multipartFiles.length]; FtpUtil.connectionFTPServer(); if (!ftpClient.isConnected()) { logger.info("==============FTP服务已断开=============="); return null; } if (ftpClient != null) { InputStream inputStream = null; try { if(StringUtils.isNotEmpty(folder)){ FtpUtil.mkDir(folder); } for (int i = 0; i < multipartFiles.length; i++) { filesSaveUrls[i] = FtpUtil.FTP_PATH; inputStream = multipartFiles[i].getInputStream(); if(StringUtils.isNotEmpty(folder)){ filesSaveUrls[i] += "/"+folder; } ftpClient.setBufferSize(100000); ftpClient.setControlEncoding("utf-8"); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.storeFile(new String(newFileNames[i].getBytes(), "iso-8859-1"), inputStream); filesSaveUrls[i] += "/"+newFileNames[i]; } } catch (Exception e) { FtpUtil.close(); e.printStackTrace(); return null; } finally { try { if (ftpClient.isConnected()) { FtpUtil.close(); } inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return filesSaveUrls; } /** * 根据文件url下载文件 * * @param path 被下载文件url * @return 文件流对象 * @throws IOException */ public static final InputStream downLoadFile(String path,String filaName){ FtpUtil.connectionFTPServer(); if (!ftpClient.isConnected()) { logger.info("==============FTP服务已断开=============="); return null; } ftpClient.enterLocalPassiveMode(); FtpUtil.changeDir(path); try { return ftpClient.retrieveFileStream(filaName); } catch (IOException e) { logger.info("==============获取文件异常=============="); e.printStackTrace(); return null; }finally{ if (ftpClient.isConnected()) { FtpUtil.close(); } } } /** * 返回FTP目录下的文件列表 * * @param pathName * @return */ public static String[] getFileNameList(String pathName) { if (!ftpClient.isConnected()) { return null; } try { return ftpClient.listNames(pathName); } catch (IOException e) { e.printStackTrace(); return null; } } /** * 删除FTP上的文件 * * @param ftpDirAndFileName * 路径开头不能加/,比如应该是test/filename1 * @return */ public static boolean deleteFile(String ftpDirAndFileName) { if (!ftpClient.isConnected()) { FtpUtil.connectionFTPServer(); } try { return ftpClient.deleteFile(ftpDirAndFileName); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 删除FTP目录 * * @param ftpDirectory * @return */ public static boolean deleteDirectory(String ftpDirectory) { if (!ftpClient.isConnected()) { return false; } try { return ftpClient.removeDirectory(ftpDirectory); } catch (IOException e) { e.printStackTrace(); return false; } } /** * 关闭链接 */ public static void close() { try { if (ftpClient != null && ftpClient.isConnected()) { ftpClient.disconnect(); } } catch (Exception e) { e.printStackTrace(); } } ———————————————— 原文链接:https://blog.csdn.net/brianang/article/details/78727835
-
一、ftp简介 文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层, TCP 模型的第四层, 即应用层, 使用 TCP 传输而不是 UDP, 客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。 FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。然而, 用户并不真正登录到自己想要存取的计算机上面而成为完全用户, 可用FTP程序访问远程资源, 实现用户往返传输文件、目录管理以及访问电子邮件等等, 即使双方计算机可能配有不同的操作系统和文件存储方式。 1.1工作流程 在传输文件时,FTP 客户端程序先与服务器建立连接,然后向服务器发送命令。服务器收到命令后给予响应,并执行命令。FTP 协议与操作系统无关,任何操作系统上的程序只要符合 FTP 协议,就可以相互传输数据 1.2工作模式 FTP支持两种模式:Standard (PORT方式,主动方式),Passive (PASV,被动方式) 1.3传输方式 FTP的传输有两种方式:ASCII、二进制 二、windows开启ftp服务 在自己的电脑上可以开启一个ftp服务用于测试。 1:打开控制面板—>程序—>启动或关闭windows功能 找到互联网信息服务勾选其中的ftp服务器,web管理,万维网服务。 系统就会安装IIS服务管理器了,安装过程可能需要等待几分钟。 2:回到电脑桌面,右击“计算机”,点击 管理,进入计算机管理界面。在这里,我们就可以看到刚刚添加的IIS服务,接下来的操作就像我们在VPS主机上添加网站差不多的操作步骤了。选中IIS服务——>网站——>右键添加FTP站点 3:设置ftp基本信息。路径为远程连接的工作路径 选取本机的IP地址,SSL如果不涉密可以选无。 这里权限先这样设置之后再修改,点击完成即可。 保存后在此后即可看到添加的ftp服务。可以这样开启多个。 注意: 要想通过java程序连接FTP在这里我新建了一个FTP的用户,新建一个用户ftptest,密码:123456,如下所示 这里注意一定要把√取消掉确定完成新建,之后修改FTP服务器设置,添加这个特定用户。 点击创建的ftp名称—>ftp身份验证—>修改身份认证,禁止匿名身份 返回最开始的页面,添加刚才创建的用户,如果创建用户对勾选着可能添加不成功。 输入刚才新建的用户名和密码,完成 如何测试刚才新建的用户是否有效嘞有好多种方法常用的是CMD命令行和下面介绍的这种 打开我的电脑在最上面输入 ftp://+FTP之前设置的IP地址 我的是ftp://192.168.10.11/回车 输入用户和密码即可登录 注意:如果输入后弹出FTP文件夹错误,需要查看一下防火墙是否放行FTP服务器 解决方式: 1、打开防火墙,点击允许应用或功能通过Windows Defender防火墙 2、找到FTP服务器并勾选,然后点击确定 三、java连接ftp org.apache.commons.net提供了对FTP的开发,引入以下依赖 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.9.0</version> </dependency> 3.1ftp工具类 连接ftp服务 @Slf4j public class FtpClient { /** * FTP服务地址 */ private static String FTP_IP; /** * FTP端口号 */ private static Integer FTP_PORT; /** * FTP用户名 */ private static String FTP_USER; /** * FTP密码 */ private static String FTP_PASSWORD; /** * FTP根路径 */ private static String FTP_PATH; /** * 映射盘符 */ private static String FTP_DRIVELETTER; private static FTPClient ftpClient; static { try { // 根据该类的class文件获取到yaml文件 Yaml yaml = new Yaml(); URL resource = FtpClient.class.getClassLoader().getResource("application-dev.yml"); assert resource != null; // 把yaml文件加载到对象中 Object obj = yaml.load(new FileInputStream(resource.getFile())); // 解析对象中的属性并赋值 JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj)); JSONObject ftp = jsonObject.getObject("fanhai", JSONObject.class).getObject("ftp", JSONObject.class); FTP_IP = String.valueOf(ftp.get("ip")); FTP_PORT = Integer.valueOf(String.valueOf(ftp.get("port"))); FTP_USER = String.valueOf(ftp.get("username")); FTP_PASSWORD = String.valueOf(ftp.get("password")); } catch (Exception e) { e.printStackTrace(); } } public static FTPClient getFtpConnection() { ftpClient = new FTPClient(); try { //连接 ftpClient.connect(FtpClient.FTP_IP, FtpClient.FTP_PORT); //设置编码 ftpClient.setControlEncoding("UTF-8"); //设置传输文件类型 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //登录 ftpClient.login(FtpClient.FTP_USER, FtpClient.FTP_PASSWORD); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { log.info("==============未连接到FTP,用户名或密码错误================="); //拒绝连接 ftpClient.disconnect(); } else { log.info("==============连接到FTP成功================="); } } catch (SocketException e) { e.printStackTrace(); log.info("==============FTP的IP地址错误=============="); } catch (IOException e) { e.printStackTrace(); log.info("==============FTP的端口错误=============="); } return ftpClient; } public static void closeConnect() { log.warn("关闭ftp服务器"); try { if (ftpClient != null) { ftpClient.logout(); ftpClient.disconnect(); } } catch (Exception e) { e.printStackTrace(); } } } ftp工具类,进行文件的上传、下载操作 ———————————————— 原文链接:https://blog.csdn.net/weixin_44486583/article/details/130319858
-
用java实现ftp文件上传。我使用的是commons-net-1.4.1.zip。其中包含了众多的java网络编程的工具包。 1 把commons-net-1.4.1.jar包加载到项目工程中去。 2 看如下代码: import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; public class FileTool { /** * Description: 向FTP服务器上传文件 * @Version 1.0 * @param url FTP服务器hostname * @param port FTP服务器端口 * @param username FTP登录账号 * @param password FTP登录密码 * @param path FTP服务器保存目录 * @param filename 上传到FTP服务器上的文件名 * @param input 输入流 * @return 成功返回true,否则返回false * */ public static boolean uploadFile(String url,// FTP服务器hostname int port,// FTP服务器端口 String username, // FTP登录账号 String password, // FTP登录密码 String path, // FTP服务器保存目录 String filename, // 上传到FTP服务器上的文件名 InputStream input // 输入流 ){ boolean success = false; FTPClient ftp = new FTPClient(); ftp.setControlEncoding("GBK"); try { int reply; ftp.connect(url, port);// 连接FTP服务器 // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 ftp.login(username, password);// 登录 reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return success; } ftp.setFileType(FTPClient.BINARY_FILE_TYPE); ftp.makeDirectory(path); ftp.changeWorkingDirectory(path); ftp.storeFile(filename, input); input.close(); ftp.logout(); success = true; } catch (IOException e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return success; } /** * 将本地文件上传到FTP服务器上 * */ public static void upLoadFromProduction(String url,// FTP服务器hostname int port,// FTP服务器端口 String username, // FTP登录账号 String password, // FTP登录密码 String path, // FTP服务器保存目录 String filename, // 上传到FTP服务器上的文件名 String orginfilename // 输入流文件名 ) { try { FileInputStream in = new FileInputStream(new File(orginfilename)); boolean flag = uploadFile(url, port, username, password, path,filename, in); System.out.println(flag); } catch (Exception e) { e.printStackTrace(); } } //测试 public static void main(String[] args) { upLoadFromProduction("192.168.13.32", 21, "hanshibo", "han", "韩士波测试", "hanshibo.doc", "E:/temp/H2数据库使用.doc"); } } 3 直接运行。即可把指定的文件上传到ftp服务器.有需要jar包的可以到我的资源中去下载。 结束! ———————————————— 原文链接:https://blog.csdn.net/atomcrazy/article/details/8943194
-
Java FTP 文件上传、下载与删除在现代软件开发中,文件传输是一项常见的需求。FTP(File Transfer Protocol)是一个用于在网络上进行文件传输的标准协议。在Java中,我们可以利用Apache Commons Net库来实现FTP的文件上传、下载和删除操作。本文将逐步讲解如何使用Java进行FTP操作,并提供相应的代码示例。准备工作在开始之前,我们需要引入Apache Commons Net库。在你的Java项目中添加以下依赖(如果使用Maven):登录后复制<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.8.0</version></dependency>FTP客户端基本操作1. 连接FTP服务器首先,我们需要连接到FTP服务器。以下代码示范了如何建立连接并登陆到FTP服务器:登录后复制import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import java.io.IOException;public class FTPExample {private FTPClient ftpClient;public void connect(String server, int port, String user, String password) throws IOException {ftpClient = new FTPClient();ftpClient.connect(server, port);ftpClient.login(user, password);ftpClient.enterLocalPassiveMode(); // 被动模式ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置二进制文件类型}}2. 文件上传文件上传是FTP操作中最常见的需求之一。我们可以使用storeFile方法将文件上传到服务器。以下是上传文件的代码示例:登录后复制import java.io.FileInputStream;import java.io.IOException;public void uploadFile(String localFilePath, String remoteFilePath) throws IOException {try (FileInputStream inputStream = new FileInputStream(localFilePath)) {boolean done = ftpClient.storeFile(remoteFilePath, inputStream);if (done) {System.out.println("File uploaded successfully.");} else {System.out.println("File upload failed.");}}}3. 文件下载与文件上传类似,下载文件可以使用retrieveFile方法。以下是下载文件的代码示例:登录后复制import java.io.FileOutputStream;public void downloadFile(String remoteFilePath, String localFilePath) throws IOException {try (FileOutputStream outputStream = new FileOutputStream(localFilePath)) {boolean done = ftpClient.retrieveFile(remoteFilePath, outputStream);if (done) {System.out.println("File downloaded successfully.");} else {System.out.println("File download failed.");}}}4. 文件删除删除文件可以通过deleteFile方法来实现。下面的示例代码演示了如何删除FTP服务器上的文件:登录后复制public void deleteFile(String remoteFilePath) throws IOException {boolean done = ftpClient.deleteFile(remoteFilePath);if (done) {System.out.println("File deleted successfully.");} else {System.out.println("File deletion failed.");}}完整示例以下是一个完整的Java FTP客户端示例,组合了上述所有操作:登录后复制public class FTPClientExample {private FTPClient ftpClient;public FTPClientExample() {ftpClient = new FTPClient();}public void connect(String server, int port, String user, String password) throws IOException {ftpClient.connect(server, port);ftpClient.login(user, password);ftpClient.enterLocalPassiveMode();ftpClient.setFileType(FTP.BINARY_FILE_TYPE);}public void uploadFile(String localFilePath, String remoteFilePath) throws IOException {try (FileInputStream inputStream = new FileInputStream(localFilePath)) {boolean done = ftpClient.storeFile(remoteFilePath, inputStream);if (done) {System.out.println("File uploaded successfully.");}}}public void downloadFile(String remoteFilePath, String localFilePath) throws IOException {try (FileOutputStream outputStream = new FileOutputStream(localFilePath)) {boolean done = ftpClient.retrieveFile(remoteFilePath, outputStream);if (done) {System.out.println("File downloaded successfully.");}}}public void deleteFile(String remoteFilePath) throws IOException {boolean done = ftpClient.deleteFile(remoteFilePath);if (done) {System.out.println("File deleted successfully.");}}public void disconnect() throws IOException {if (ftpClient.isConnected()) {ftpClient.logout();ftpClient.disconnect();}}}状态图示例我们可以使用状态图来描述FTP操作的状态变化。以下是一个简单的状态图示例,描述了文件上传、下载和删除的过程:DisconnectedConnectingConnectedUploadingUploadCompleteDownloadingDownloadCompleteDeletingDeleteCompleteDisconnecting数据统计在实际应用中,我们可能需要监控不同操作的状态,下面是用饼状图示例展示的一些简单统计数据。例如,统计在某一时间段内的文件操作:FTP 文件操作统计上传下载删除结尾通过本系列的示例代码,您可以在Java中轻松实现FTP文件的上传、下载和删除操作。在构建需要文件传输功能的应用时,掌握FTP的基本操作是非常重要的。这不仅可以帮助提高应用的处理效率,也能提升用户体验。原文链接:https://blog.51cto.com/u_16175522/11615875
-
概要 在实现网络编程时,需要了解很多协议,FTP协议就是很重要的一个,这篇文章主要写对于Java在基于FTP协议实现网络编程时的一些简单操作即工具类的一些简单应用方式,例如,文件的上传下载,寻找目录和创建等。 实现过程(操作代码和相关解释) 首先你要知道ftp的ip,路径,端口,有操作权限的账号和密码 导入jar包 导入commons-net 下载commons-net https://mvnrepository.com/artifact/commons-net/commons-net/3.6 或者 <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.6</version> </dependency> 连接FTP服务器 String ip = "192.168.59.215"; int port = 21; String userName = "admin"; String passWord = "123456"; // 创建基于FTP协议访问文件客户端的对象 FTPClient client = new FTPClient(); try { client.connect(ip,21); client.login(userName,passWord); } catch (SocketException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } 获取当前文件夹目录 // 设置日期格式 SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日"); // 获取当前文件夹目录中的所有文件 FTPFile[] ftpFileList = client.listFiles(); for (FTPFile ftpFile : ftpFileList) { // 文件名称中包含中文乱码 String fileName = ftpFile.getName(); /** * FTP协议里面,规定文件名编码为iso-8859-1 * gb2312--编码集 **/ fileName = new String(fileName.getBytes("iso-8859-1"),"gb2312"); System.out.println("文件名称:"+fileName); Date createDate = ftpFile.getTimestamp().getTime(); System.out.println("文件创建时间:"+fmt.format(createDate)); System.out.println("文件大小:"+ftpFile.getSize()); } 查找和创建文件夹 String fileName = "FJQ_shuaizhao"; // 创建并切换至个人 Boolean ischange = ftpClient.changeWorkingDirectory(fileName); // 判断文件存在与否 if (!ischange) { // 创建文件夹 ftpClient.makeDirectory(fileName); // 切换文件夹 ftpClient.changeWorkingDirectory(fileName); }else{ ftpClient.changeWorkingDirectory(fileName); } 文件上传 try(FileInputStream in = new FileInputStream("本地文件上传路径")) { // 文件上传 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 存文件 ftpClient.storeFile(System.currentTimeMillis()+".jpg", in); } 文件下载 try(FileOutputStream out = new FileOutputStream("本地文件保存路径")) { // 下载指定格式文件-二进制格式BINARY_FILE_TYPE ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 下载文件 Boolean isRetrieve = ftpClient.retrieveFile("fjq.jpg", out); System.out.println("下载成功?"+isRetrieve); } catch (IOException e) { e.printStackTrace(); } finally { try { ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } } 关闭连接 try { ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } 技术名词解释 FTP(File Transfer Protocol):是应用层的一个文件传输协议 。主要作用是在服务器和客户端之间实现文件的传输和共享。FTP协议运行在TCP连接上,保证了文件传输的可靠性。在传输时,传输双方的操作系统、磁盘文件系统类型可以不同。 FTP协议:允许TCP/IP网络上的两台计算机之间进行文件传输。而FTP服务是基于FTP协议的文件传输服务。工作时,一台计算机上运行FTP客户端应用程序,另一台计算机上需要运行FTP服务器端程序。只有拥有了FTP服务,客户端才能进行文件传输。 小结 基于Java和FTP的网络编程,一些简单的操作,对于初学者来说有一定帮助。 ———————————————— 原文链接:https://blog.csdn.net/q_qwp_p/article/details/131612866
-
清华大学出版社《Java程序员,上班那点事儿》作者:钟声——第10章《高手有多高菜鸟有多菜》部分节选。 大家也许都用过FTP上传下载工具,比如“LeapFTP”这个工具是一个很方便的FTP服务器上传下载工具,如图所示。这个工具很方便,输入用户名密码以后,就可以看到FTP服务器端的文件列表,便于进行上传与下载操作。 你是否试过自己用Java编写一个FTP的文件上传与下载应用程序? Java也可以开发出这样的程序来,并不复杂,我们先看看,利用Java的FTP类工具包制作FTP应用程序的开发是怎么做的,请看如下程序: import sun.net.*; import sun.net.ftp.*; public class FTP { public static void main(String[] args) { String server="192.168.0.12"; //输入的FTP服务器的IP地址 String user="useway"; //登录FTP服务器的用户名 String password=" !@#$%abce"; //登录FTP服务器的用户名的口令 String path="/home/useway"; //FTP服务器上的路径 try { FtpClient ftpClient=new FtpClient(); //创建FtpClient对象 ftpClient.openServer(server); //连接FTP服务器 ftpClient.login(user, password); //登录FTP服务器 if (path.length()!=0) ftpClient.cd(path); TelnetInputStream is=ftpClient.list(); int c; while ((c=is.read())!=-1) { System.out.print((char)c); } is.close(); ftpClient.closeServer();//退出FTP服务器 } catch(Exception ex){ } } } 如果你感兴趣的话,可以自己写一个这个程序,当本程序运行以后,我们看到如图所示的情况,列出了服务器端程序的目录内容。 这个程序是一个简单的得到FTP服务器端文件列表的程序,但不要误会,这个程序可称不上“网络应用层协议”程序的开发! 这个程序仅仅是利用“sun.net.*;”和“sun.net.ftp.*;”中的相关类进行的对FTP端的操作的,我们根本没有利用Java的Socket的在网络层面向FTP服务器端发送任何请求,而是通过Java提供的工具包,向服务器端发送的链接请求。 利用Java的FTP包来链接FTP服务器的好处在于我们不需要关心网络层面发送数据的具体细节,而只要调用相应的方法就行了。利用Java的FTP包来链接FTP服务器的缺点是使开发者不知道应用层协议收发的来龙去脉,搞不清楚其中原理,对底层数据的把握程度非常弱。 讲到这里有程序员会问:“那么FTP在网络层面和PC与服务器间是如何交互的呢?”,好,就给大家列出FTP协议交互过程。 请看下面的一段FTP协议交互的例子: FTP服务器: 220 (vsFTPd 2.0.1) FTP客户端: USER useway FTP服务器: 331 Please specify the password. FTP客户端: PASS !@#$%abce FTP服务器: 230 Login successful. FTP客户端: CWD /home/useway FTP服务器: 250 Directory successfully changed. FTP客户端: EPSV ALL FTP服务器: 200 EPSV ALL ok. FTP客户端: EPSV FTP服务器: 229 Entering Extended Passive Mode (|||62501|) FTP客户端: LIST FTP服务器: 150 Here comes the directory listing. FTP服务器: 226 Directory send OK. FTP客户端: QUIT FTP服务器: 221 Goodbye. 以上这段文字其实就是FTP服务器和FTP客户端之间相互交互的过程,它们之间传递信息的协议是TCP协议,互相发送的内容就是上面这段文字所写的内容。 我们下面逐步的去解释每一句话的含义: FTP服务器: 220 (vsFTPd 2.0.1) |说明:链接成功 FTP客户端: USER useway |说明:输入用户名 FTP服务器: 331 Please specify the password. |说明:请输入密码 FTP客户端: PASS !@#$%abce |说明:输入密码 FTP服务器: 230 Login successful. |说明:登录成功 FTP客户端: CWD /home/useway |说明:切换目录 FTP服务器: 250 Directory successfully changed. |说明:目录切换成功 FTP客户端: EPSV ALL |说明:为EPSV被动链接方式 FTP服务器: 200 EPSV ALL ok. |说明:OK FTP客户端: EPSV |说明:链接 FTP服务器: 229 Entering Extended Passive Mode (|||62501|) |说明:被动链接端口为62501 FTP客户端: LIST |说明:执行LIST显示文件列表 FTP服务器: 150 Here comes the directory listing. |说明:列表从62501端口被发送 FTP服务器: 226 Directory send OK. |说明:发送完成 FTP客户端: QUIT |说明:退出FTP FTP服务器: 221 Goodbye. |说明:再见 有了以上文字的内容,我们不需要任何工具也可以得到FTP文件列表了,不信你跟着我一起做一遍。 第一步:首先打开CMD进入DOS命令行模式,键入: telnet 192.168.0.1 21[回车] 说明:Telnet 到Ftp服务器的21端口。 执行该命令 大家发现什么问题了吗? 提示的内容正好就是,我们上面一段文字的第一句:220 (vsFTPd 2.0.1),这说明FTP服务器已经接受了我们的链接,已经可以进行下一步操作了。 第二步:将后面的一系列发送内容逐个键入: USER useway[回车] PASS !@#$%abce[回车] CWD /home/useway[回车] EPSV ALL[回车] EPSV[回车] 好,这回FTP服务器给出了一系列的回应,在最后给出了一个新的端口号"58143"。 第三步:再打开一个新的CMD窗口,键入: telnet 192.168.0.1 58143[ 回车 ] 注意,这次Telnet请求链接服务器的端口号是“58143”,是FTP服务器给我们的一个链接端口。链接后,窗口为空白没有任何提示,如图所示。 第四步:回到第一个CMD窗口,键入: LIST[ 回车 ] 第五步:这时候第二CMD窗口就接收到了文件列表: 第二个窗口接收到了文件列表如图所示。 第六步:退出操作 QUIT[ 回车 ] 执行完成后,失去与主机的链接。 大家看到了吧,FTP协议就是这样的一个交互过程,利用系统自带的Telnet工具也可以完成FTP的这些基本命令的操作。如果,你想用Java的Socket完成以上操作就只需要一步一步的按照上述内容发送字符串给FTP服务器端就行了。 我们下面也给出例子代码: import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class FTPClient{ public static void main(String[] args) throws Exception{ Socket socket = new Socket("192.168.0.1",21); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); //接收初始链接信息 byte[] buffer = new byte[100]; int length = is.read(buffer); String s = new String(buffer, 0, length); System.out.println(s); //发送用户名 String str = "USER useway\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //发送密码 str = "PASS !@#$%abcd\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //发送切换文件夹指令 str = "CWD /home/useway\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //设置模式 str = "EPSV ALL\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //得到被动监听信息 str = "EPSV\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //取得FTP被动监听的端口号 String portlist=s.substring(s.indexOf("(|||")+4,s.indexOf("|)")); System.out.println(portlist); //实例化ShowList线程类,链接FTP被动监听端口号 ShowList sl=new ShowList(); sl.port=Integer.parseInt(portlist); sl.start(); //执行LIST命令 str = "LIST\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //关闭链接 is.close(); os.close(); socket.close(); } } //得到被动链接信息类,这个类是多线程的 class ShowList extends Thread{ public int port=0; public void run(){ try{ Socket socket = new Socket("192.168.0.1",this.port); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); byte[] buffer = new byte[10000]; int length = is.read(buffer); String s = new String(buffer, 0, length); System.out.println(s); //关闭链接 is.close(); os.close(); socket.close(); } catch(Exception ex){ } } } 该程序运行后得到的运行结果如图所示,基本上和上面的运行效果相同吧,底层又如何,无非是将那些封装好的方法解开来运行,只要了解到了它们运行的规则,我们自己可以开发出一样的程序来 ———————————————— 原文链接:https://blog.csdn.net/weixin_33854644/article/details/85128720
上滑加载中
推荐直播
-
华为云码道 × 仓颉编程:工程化AI编码探索2026/05/27 周三 19:00-21:00
刘俊杰-华为云仓颉语言专家/李炎-华为云码道技术专家/王智鹏-OpenCangjie开源社区发起人
本场直播围绕华为云仓颉语言与华为云码道的深度结合,展示华为云智能编程从零基础到高效落地的完整生态能力。以华为云码道为引擎,仓颉语言为载体,带给大家日常提效、趣味创新到极速量产的开发体验。
回顾中
热门标签