|
|
资讯缩略图:
资讯发布日期:2026-05-18
资讯发布简介:AIWROK软件安卓脚本FTP上传下载例子
资讯关键词:AIWROK软件安卓脚本FTP上传下载例子
资讯所属分类:IT资讯
联系:
① 本信息收集于网络,如有不对的地方欢迎联系我纠正! ② 本信息免费收录,不存在价格的问题! ③ 如果您的网站也想这样出现在这里,请您加好友情链接,我当天会审核通过!
④友情链接关键字:软件网站分类目录 网址:http://www.postbbs.com/
资讯详细描述
 | |  |  | AIWROK软件安卓 脚本FTP上传下载例子
- /**
- * AIWROK 简易FTP工具 - 纯Java Socket实现
- * 交流QQ群: 711841924 (群一) / 528816639 (苹果脚本内测群)s
- */
- // ==================== FTP配置 ====================
- // 配置FTP服务器连接信息
- var FTPConfig = {
- host: "38.67.75.157", // FTP服务器地址
- port: 21, // FTP端口(默认21)
- username: "fghgdfhfdh", // 登录用户名
- password: "aH6CEtK6X77J", // 登录密码
- timeout: 60000, // 连接超时时间(毫秒)
- encoding: "UTF-8" // 字符编码
- };
- // ==================== FTP客户端 ====================
- // 使用IIFE(立即执行函数)创建FTPClient对象
- // 封装所有FTP操作,保持全局命名空间清洁
- var FTPClient = (function() {
- // 私有变量 - FTP连接状态
- var controlSocket = null; // 控制通道Socket(发送命令)
- var dataSocket = null; // 数据通道Socket(传输文件)
- var reader = null; // 控制通道读取器
- var writer = null; // 控制通道写入器
- var isConnected = false; // 连接状态标志
- /**
- * 读取FTP服务器响应
- * 从控制通道读取一行文本
- * @returns {string|null} 服务器响应的文本,失败返回null
- */
- function readResponse() {
- try {
- var line = reader.readLine();
- if (line) console.log("FTP: " + line);
- return line;
- } catch (e) {
- return null;
- }
- }
- /**
- * 发送FTP命令并等待响应
- * @param {string} cmd - FTP命令(如 USER, PASS, PASV等)
- * @returns {string|null} 服务器响应,失败返回null
- */
- function sendCommand(cmd) {
- try {
- writer.write(cmd + "\r\n"); // FTP命令以\r\n结尾
- writer.flush(); // 立即发送
- sleep.second(0.5); // 等待服务器响应
- return readResponse(); // 读取响应
- } catch (e) {
- return null;
- }
- }
- /**
- * 连接FTP服务器并登录
- * 建立控制通道,完成用户认证
- * @param {Object} config - FTP配置对象(host, port, username, password等)
- * @returns {boolean} 连接成功返回true,失败返回false
- */
- function connect(config) {
- try {
- console.log("连接FTP: " + config.host);
-
- // 1. 创建控制通道Socket连接
- controlSocket = new java.net.Socket(config.host, config.port);
- controlSocket.setSoTimeout(config.timeout); // 设置超时
-
- // 2. 创建输入输出流(使用指定编码)
- var InputStreamReader = java.io.InputStreamReader;
- var OutputStreamWriter = java.io.OutputStreamWriter;
- var BufferedReader = java.io.BufferedReader;
- var BufferedWriter = java.io.BufferedWriter;
-
- reader = new BufferedReader(new InputStreamReader(controlSocket.getInputStream(), config.encoding));
- writer = new BufferedWriter(new OutputStreamWriter(controlSocket.getOutputStream(), config.encoding));
-
- // 3. 读取服务器欢迎消息(220开头)
- var welcome = readResponse();
- if (!welcome || !welcome.startsWith("220")) {
- disconnect();
- return false;
- }
-
- // 4. 读取所有多行欢迎消息(Pure-FTPd会发送多条220-开头的消息)
- sleep.second(0.3);
- var line;
- while ((line = reader.readLine()) !== null) {
- if (!line.startsWith("220-")) break; // 遇到非220-的行就停止
- }
-
- // 5. 发送用户名(USER命令)
- var resp = sendCommand("USER " + config.username);
- if (!resp || !resp.startsWith("331")) { // 331表示需要密码
- disconnect();
- return false;
- }
-
- // 6. 发送密码(PASS命令)
- resp = sendCommand("PASS " + config.password);
- if (!resp || !resp.startsWith("230")) { // 230表示登录成功
- disconnect();
- return false;
- }
-
- console.log("✓ 登录成功");
- isConnected = true;
- return true;
-
- } catch (e) {
- console.log("连接失败: " + e.message);
- disconnect();
- return false;
- }
- }
- /**
- * 设置被动模式(PASV)
- * FTP被动模式:服务器开启数据端口,客户端连接
- * 自动处理内网IP映射(将10.x.x.x替换为公网IP)
- * @returns {boolean} 设置成功返回true,失败返回false
- */
- function setupPassiveMode() {
- try {
- // 关闭旧的数据通道
- if (dataSocket) {
- try { dataSocket.close(); } catch(e) {}
- dataSocket = null;
- }
-
- // 发送PASV命令,获取服务器数据端口
- var resp = sendCommand("PASV");
- if (!resp || !resp.startsWith("227")) return false; // 227表示进入被动模式
-
- // 解析PASV响应: 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)
- var match = resp.match(/\(([^)]+)\)/);
- if (!match) return false;
-
- var parts = match[1].split(",");
- var port = parseInt(parts[4]) * 256 + parseInt(parts[5]); // 计算端口号
- var ip = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
-
- // 重要:如果服务器返回内网IP,替换为配置的公网IP
- // 这是因为FTP服务器在NAT后面,会返回内网地址
- if (ip.startsWith("10.") || ip.startsWith("192.168.")) {
- console.log("检测到内网IP: " + ip + ",使用服务器地址: " + FTPConfig.host);
- ip = FTPConfig.host;
- }
-
- // 创建数据通道Socket连接
- dataSocket = new java.net.Socket(ip, port);
- dataSocket.setSoTimeout(60000); // 数据传输超时60秒
- return true;
- } catch (e) {
- console.log("被动模式设置失败: " + e.message);
- return false;
- }
- }
- /**
- * 上传文件到FTP服务器
- * 使用被动模式传输,支持二进制文件
- * @param {string} localPath - 本地文件路径(如 /sdcard/test.txt)
- * @param {string} remotePath - 远程文件路径(如 /test.txt)
- * @returns {boolean} 上传成功返回true,失败返回false
- */
- function upload(localPath, remotePath) {
- if (!isConnected) return false;
-
- console.log("上传: " + localPath + " -> " + remotePath);
-
- // 检查本地文件是否存在
- var file = new java.io.File(localPath);
- if (!file.exists()) {
- console.log("文件不存在: " + localPath);
- return false;
- }
-
- // 设置被动模式,建立数据通道
- if (!setupPassiveMode()) return false;
-
- // 发送STOR命令,准备接收文件
- var resp = sendCommand("STOR " + remotePath);
- if (!resp || !resp.startsWith("150")) return false; // 150表示准备接收
-
- // 读取本地文件并发送到数据通道
- var fis = new java.io.BufferedInputStream(new java.io.FileInputStream(file));
- var out = dataSocket.getOutputStream();
- var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096); // 4KB缓冲区
- var len;
-
- while ((len = fis.read(buffer)) !== -1) {
- out.write(buffer, 0, len); // 写入数据通道
- }
-
- // 关闭流和Socket
- fis.close();
- out.close();
- dataSocket.close();
- dataSocket = null;
-
- // 读取最终响应(226表示传输完成)
- sleep.second(0.5);
- var finalResp;
- while ((finalResp = readResponse()) !== null) {
- if (finalResp.startsWith("226 ")) { // 226表示文件传输成功
- console.log("✓ 上传成功");
- return true;
- }
- }
-
- return false;
- }
- /**
- * 从FTP服务器下载文件
- * 使用被动模式传输,支持二进制文件
- * @param {string} remotePath - 远程文件路径(如 /test.txt)
- * @param {string} localPath - 本地保存路径(如 /sdcard/test.txt)
- * @returns {boolean} 下载成功返回true,失败返回false
- */
- function download(remotePath, localPath) {
- if (!isConnected) return false;
-
- console.log("下载: " + remotePath + " -> " + localPath);
-
- // 设置被动模式,建立数据通道
- if (!setupPassiveMode()) return false;
-
- // 发送RETR命令,请求下载文件
- var resp = sendCommand("RETR " + remotePath);
- if (!resp || !resp.startsWith("150")) return false; // 150表示准备发送
-
- // 从数据通道接收数据并保存到本地文件
- var fos = new java.io.BufferedOutputStream(new java.io.FileOutputStream(new java.io.File(localPath)));
- var input = dataSocket.getInputStream();
- var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096); // 4KB缓冲区
- var len;
- var total = 0;
-
- console.log("开始接收...");
- try {
- var startTime = new Date().getTime();
- var timeout = 30000; // 30秒超时保护
-
- while ((len = input.read(buffer)) !== -1) {
- fos.write(buffer, 0, len); // 写入本地文件
- total += len;
-
- // 检查是否超时
- var elapsed = new Date().getTime() - startTime;
- if (elapsed > timeout) {
- console.log("超时: 已接收 " + total + " 字节");
- break;
- }
- }
- console.log("接收完成: " + total + " 字节");
- } catch (e) {
- console.log("接收出错: " + e.message);
- }
-
- // 关闭流和Socket
- fos.close();
- input.close();
- dataSocket.close();
- dataSocket = null;
-
- // 读取最终响应(226表示传输完成)
- sleep.second(0.5);
- var finalResp;
- while ((finalResp = readResponse()) !== null) {
- if (finalResp.startsWith("226 ")) { // 226表示文件传输成功
- console.log("✓ 下载成功");
- return true;
- }
- }
-
- return false;
- }
- /**
- * 获取FTP目录列表
- * 使用LIST命令获取指定目录的文件列表
- * @param {string} remotePath - 远程目录路径(如 /)
- * @returns {Array} 文件列表数组,每个元素是一行LIST输出
- */
- function listDir(remotePath) {
- if (!isConnected) return [];
-
- console.log("列出目录: " + remotePath);
-
- // 设置被动模式
- if (!setupPassiveMode()) return [];
-
- // 发送LIST命令
- var resp = sendCommand("LIST " + remotePath);
- if (!resp || !resp.startsWith("150")) return []; // 150表示准备发送数据
-
- // 从数据通道读取目录列表
- var dirReader = new java.io.BufferedReader(
- new java.io.InputStreamReader(dataSocket.getInputStream(), "UTF-8")
- );
-
- var files = [];
- var line;
- while ((line = dirReader.readLine()) !== null) {
- if (line.trim()) files.push(line); // 跳过空行
- }
-
- // 关闭读取器和Socket
- dirReader.close();
- dataSocket.close();
- dataSocket = null;
-
- // 读取最终响应(226表示传输完成)
- sleep.second(0.5);
- var finalResp;
- while ((finalResp = readResponse()) !== null) {
- if (finalResp.startsWith("226 ")) break; // 找到最终的226响应
- }
-
- console.log("找到 " + files.length + " 个条目");
- return files;
- }
- /**
- * 断开FTP连接
- * 关闭所有Socket和流,释放资源
- */
- function disconnect() {
- try {
- // 关闭数据通道
- if (dataSocket) {
- try { dataSocket.close(); } catch(e) {}
- dataSocket = null;
- }
-
- // 关闭控制通道
- if (controlSocket) {
- try {
- writer.write("QUIT\r\n"); // 发送QUIT命令
- writer.flush();
- } catch(e) {}
- try { controlSocket.close(); } catch(e) {}
- controlSocket = null;
- }
-
- // 关闭流
- if (reader) { try { reader.close(); } catch(e) {} reader = null; }
- if (writer) { try { writer.close(); } catch(e) {} writer = null; }
-
- isConnected = false;
- console.log("已断开");
- } catch (e) {
- // 忽略断开时的错误
- }
- }
- // 公开API - 只暴露这5个方法
- return {
- connect: connect, // 连接FTP服务器
- disconnect: disconnect, // 断开连接
- upload: upload, // 上传文件
- download: download, // 下载文件
- listDir: listDir // 获取目录列表
- };
- })();
- // ==================== 测试代码 ====================
- /**
- * 主函数 - 演示FTP工具的三个核心功能
- * 1. 连接FTP服务器
- * 2. 查看目录列表
- * 3. 上传文件
- * 4. 下载文件
- * 5. 断开连接
- */
- function main() {
- console.log("========== FTP简易工具 ==========\n");
-
- // 1. 连接FTP服务器
- if (!FTPClient.connect(FTPConfig)) {
- console.log("连接失败");
- return;
- }
-
- sleep.second(1); // 等待1秒
-
- // 2. 查看根目录文件列表
- console.log("\n--- 查看根目录 ---");
- var files = FTPClient.listDir("/");
- for (var i = 0; i < files.length; i++) {
- console.log(" " + files[i]);
- }
-
- sleep.second(1); // 等待1秒
-
- // 3. 上传文件测试
- console.log("\n--- 上传测试 ---");
- FTPClient.upload("/sdcard/test.txt", "/test_upload.txt");
-
- sleep.second(1); // 等待1秒
-
- // 4. 下载文件测试
- console.log("\n--- 下载测试 ---");
- FTPClient.download("/2.txt", "/sdcard/2_downloaded.txt");
-
- sleep.second(1); // 等待1秒
-
- // 5. 断开连接
- FTPClient.disconnect();
-
- console.log("\n========== 完成 ==========");
- }
- // 执行主函数
- main();
复制代码
| |  | |  |
|
untoAIWROK软件脚本JSON转换示例nextnocontent
|