相关文章推荐
叛逆的脸盆  ·  seam2 - ...·  1 年前    · 
不羁的风衣  ·  PTA ...·  1 年前    · 
中午吃完饭上来,再调试程序,再对比了一下。逻辑没区别啊,应该也没问题。可咋就是看不到文件。这时,我便用 filezilla 软件连接到对方FTP服务器上。开始,我怀疑是对方的FTP服务器指定的目录没有读写权限,登上去,手动上传了一个文件,并且成功了。这个时候,便可以排除没有读写权限。 那这又会是什么原因呢?这个时候,没辙,只能求助百度,google了。百度能搜索到的东西真的很少,而且讲的不全,但是这个时候,网上看到一些也碰到过这种情况的。说FTP服务器的模式有 主动模式、被动模式 两种。说的情况也和我碰到的类似。这个时候,心里就认准可能是和服务器设置的模式有关。google了一段
IMPORTANCES<span style="color:#009900;">: By default, the FTP protocol establishes a data connection by opening a port on the client and allows the server connecting to this port. This is called local active mode, but it is usually blocked by firewall so the file transfer may not work. Fortunately, the FTP protocol has another mode, local passive mode, in which a data connection is made by opening a port on the server for the client to connect – and this is not blocked by firewall.
So it is recommended to switch to local passive mode before transferring data, by invoking the methodenterLocalPassiveMode() of the FTPClient class.</span>
这句话,讲的很准确。FTPClient连接FTP服务的时候,Java中 org.apache.commons.net.ftp.FTPClient默认使用的应该是主动模式。所谓 主动模式 :就是指客户端连接服务端的时候,告诉服务端,我们之间要进行通讯,数据交换。我申请开辟一个端口,专门用于我们之间的通信,也即C(client)端主动向S(Server)端发起的请求。 被动模式 就是指,一开始服务一起来,S端变开启一个端口告诉C端,我们之间的通讯就在这个端口下。也就C端被动的接受服务端。 理清了这两种模式之后,感觉还是无从下手。这个时候由于对网络的那一块不熟悉,基本上判断不了主动模式和被动模式,因此,只能求助于我们公司负责网络运维的同事。经过他们的帮忙,从而确认了,对方使用的FTP模式为被动模式。再回到代码中,看到以前的FTP工具类 * 上传文件(主动模式)--默认的模式 * @param ip * @param port * @param userName * @param password * @param sourceStream * @param ftpDir * @param ftpFileName * @param charset * @throws FrontEndException public final static void upload(String ip, int port, String userName, String password, InputStream sourceStream, String ftpDir, String ftpFileName, String charset) throws FrontEndException { FTPClient ftpClient = new FTPClient(); try { if (port <= 0) ftpClient.connect(ip); else ftpClient.connect(ip, port); ftpClient.login(userName, password); //设置上传目录 ftpClient.changeWorkingDirectory(ftpDir); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding(charset); //设置文件类型(二进制) ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.storeFile(ftpFileName, sourceStream); } catch (IOException e) { throw new FrontEndException("上传文件失败", e); } finally { try { ftpClient.disconnect(); } catch (IOException e) { LOGGER.error("断开ftp连接异常", e); }心想,或许,真的是和这个模式有关。此时我再仔细Debug了一下。当执行到 ftpClient.storeFile(ftpFileName, sourceStream);我看到返回的是false ,那这个时候基本上可以断定是文件没有上传成功。如果服务器端使用的是被动模式,而我们使用主动模式去上传文件的话。服务器肯定不会接收的
这个时候,感觉问题应该差不多找到了。网上一搜,加上一句设置被动模式的代码 //设置被动模式  ftpClient.enterLocalPassiveMode(); 再仔细测试了一下,果然问题就出在这里。解决了。此时正确的代码为
* 被动模式---上传文件 * @param ip * @param port * @param userName * @param password * @param sourceStream * @param ftpDir * @param ftpFileName * @param charset * @throws FrontEndException public final static void uploadPassiveMode(String ip, int port, String userName, String password, InputStream sourceStream, String ftpDir, String ftpFileName, String charset) throws FrontEndException { FTPClient ftpClient = new FTPClient(); try { if (port <= 0) ftpClient.connect(ip); else ftpClient.connect(ip, port); boolean login = ftpClient.login(userName, password); StringBuilder service = new StringBuilder(); service.append("上传FTP【ip="+ip+",port="+port+"】,"); if(login){ LOGGER.info(service.append("登录成功...").toString()); //设置上传目录 ftpClient.changeWorkingDirectory(ftpDir); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding(charset); //设置被动模式 <span style="color:#ff0000;">ftpClient.enterLocalPassiveMode();</span> //设置文件类型(二进制) ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); if(ftpClient.storeFile(ftpFileName, sourceStream)){ LOGGER.info(service.append("上传成功...").toString()); } else { LOGGER.info(service.append("上传失败...").toString()); } else { LOGGER.info(service.append("登录失败...").toString()); } catch (IOException e) { throw new FrontEndException("上传文件失败", e); } finally { try { ftpClient.disconnect(); } catch (IOException e) { LOGGER.error("断开ftp连接异常", e); }同理,我们在下载对应的结果文件的时候。也需要设置相应的被动模式。 ======================附上FTP上传和下载文件时候的步骤===========================
 To properly write code to upload files to a FTP server using Apache Commons Net API, the following steps should be followed:
          Connect and login to the server.
          Enter local passive mode for data connection.
          Set file type to be transferred to binary.
          Create an InputStream for the local file.
          Construct path of the remote file on the server. The path can be absolute or relative to the current working directory.
          Call one of the storeXXX()methods to begin file transfer. There are two scenarios:
      Using an InputStream-based approach: this is the simplest way, since we let the system does the ins and outs. There is no additional code, just passing the InputStream object into the appropriate method, such as storeFile(String remote, InputStream local) method.
      Using an OutputStream-based approach: this is more complex way, but more control. Typically we have to write some code that reads bytes from the InputStream of the local file and writes those bytes into the OutputStream which is returned by the storeXXX() method, such as storeFileStream(String remote) method.
          Close the opened InputStream and OutputStream.
          Call completePendingCommand() method to complete transaction.
          Logout and disconnect from the server.
<span style="color:#ff0000;">NOTES: we should check return value of the storeXXX() and completePendingCommand() method to ensure the upload is completed successfully.</span>
最近在和一个第三方的合作 不得已需要使用FTP文件接口。由于FTP Server由对方提供,而且双方背后各自的网络环境都很不单纯等等原因,造成测试环境无法模拟实际情况。测试环境 程序一切正常,但是在部署到生产环境之后发现FTP操作不规律性出现“卡死”现象:程序捕获不到任何异常一直卡着,导致轮巡无法正常工作。 为了解决这个问题,我首先考虑的是对于 FTPClient 的使用上没...
代码是一位老哥的原创的https://www.cnblogs.com/tianhyapply/p/3721370.html 我改进了下了一行ftp.enterLocalPassiveMode(); 即PASV 模式 被动 模式 ) 成功上传! import java .io.File; import java .io.FileInputStream; import org. apache .commo...
FTPClient ftpClient = new FTPClient (); ftpClient .connect(ftpAddress, ftpPort); // 连接FTP服务器 ftpClient .login(ftpUserName, ftpPassword);// 登陆FTP服务器 ftpClient .setControlEncoding("UTF-8");// 文支持 ftpClient .setFileType( FTPClient .BINARY_FILE_TYPE)...
最近在做ftp文件上传的时候,开发测试环境上传都没有问题,但是在开发环境缺无法上传,但是也没有报错,纠结了老久。最后看到网上有说 FtpClient 主动 模式 被动 模式 之分,然后就解决了。 FTPClient 连接FTP服务的时候, Java org. apache .commons.net.ftp. FTPClient 默认使用的应该是 主动 模式 。所谓 主动 模式 :就是指客户端连接服务端的时候,告诉服务端,...
主动 模式 1. FTP client use TCP port 1026 for command to FTP server command port 21   2. FTP server use TCP port 21 responed  to FTP client command port 1026   3. FTP server use TCP port 20 for sending data to FTP client data port 1027 (1026 + 1)   4. FTP client use TCP port 1027 ( 1026 + 1) for data A
ftp上传文件报org. apache .commons.net.ftp.FTPConnectionClosedException: Connection closed without indication错误 项目 由于ftp做了迁移,代码使用的 ftpclient 登录成功,但是上传文件就报这个错误。 public boolean uploadFile(String ip, int port, String username, String password, String s import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.Record; import com.jfinal.plugin.activerecord.tx.Tx; import com.jfinal.upload.UploadFile; import org. apache .commons.net.ftp.FTP; import org. apache .commons.net.ftp. FTPClient ; import org. apache .commons.net.ftp.FTPReply; import java .io.IOException; import java .io.InputStream; public class FtpController extends Controller { public void upload() { UploadFile file = getFile("file"); boolean success = false; try { success = uploadToFtp(file.getFileName(), file.getFile()); } catch (IOException e) { e.printStackTrace(); if (success) { renderText("上传成功"); } else { renderText("上传失败"); @Before(Tx.class) public boolean uploadToFtp(String fileName, File file) throws IOException { FTPClient ftp = new FTPClient (); ftp.connect("ftp.example.com", 21); ftp.login("username", "password"); int reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return false; ftp.setFileType(FTP.BINARY_FILE_TYPE); ftp.enterLocalPassiveMode(); InputStream input = new FileInputStream(file); boolean success = ftp.storeFile(fileName, input); input.close(); ftp.logout(); ftp.disconnect(); if (success) { Record record = new Record().set("file_name", fileName); Db.save("file", record); return success; 这段代码使用了 jfinal 框架和 Apache Commons Net 库来实现 FTP 文件上传。在 uploadToFtp 方法 ,我们连接到 FTP 服务器,设置文件类型为二进制,使用 被动 模式 ,然后将文件上传到服务器。如果上传成功,我们将文件名保存到数据库 。在 upload 方法 ,我们使用 getFile 方法获取上传的文件,然后调用 uploadToFtp 方法将文件上传到 FTP 服务器。最后,我们根据上传结果返回相应的信息。 楼主: 你好像逻辑上有点偏差,你看看我说的是不是这个意思哈,你这个根本上还是复杂度的问题,只不过你的计算方法是有偏差的。 [code=javascript] const arr1 = ['a', 'b', 'c', 'd', 'e']; const arr2 = [1, 2, 3, 4]; const arr3 = ['A', 'B', 'C']; const arr4 = ['a1', 'a2']; for (let i = 0; i < arr1.length; i++) { // 这里循环 5 次 对吧? for (let j = 0; j < arr2.length; j++) { // 这里循环 4 次 对吧? for (let k = 0; k < arr3.length; k++) { // 这里循环 3 次 对吧? for (let l = 0; l < arr4.length; l++) { // 这里循环 2 次 对吧? // do something... [/code] [code=plain] | | | 'A' 'B' 'C' | | | | | | 'a1' 'a2' 'a1' 'a2' 'a1' 'a2' (1) (2) (3) (4) (5) (6) [/code] 我上面就画出一个分支出来,你看下,推倒一下,其实你会发现不是你所推算的那个计算方法,不管你说的内大小还是内小外大,复杂度都是几层循环嵌套的相乘,如果你认同我的说法,还请更正一下您的回答,毕竟这回影响到很多人,尤其是有偏差的理解 关于多层for循环迭代的效率优化问题 会飞的斗篷猿: 博主你好,我的跟您一样也是嵌套循环比较多,但是运行不起来,可以帮我看一下吗?感谢了 #include<iostream> #include<opencv2/opencv.hpp> //#include<opencv2/core/core.hpp> //#include<opencv2/imgproc/imgproc.hpp> //#include<opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; vector<Point>pt; vector<Point>newpt; void Flip(Mat& img) int rows = img.rows; int cols = img.cols; for (int i = 0; i < rows; i++) for (int j = 0; j < cols ; j++) // if (img.channels() == 1) if (img.at<uchar>(i, j) == 0) { Point newpt; newpt.x = j; newpt.y = i; pt.push_back(newpt); //newpt.x = (j - sp.x) * (_X- _x);/dx ; //newpt.y= (sp.y - i) * (_Y - _y)/dy ; //cout << j << "," << i<<endl; // } /* else if (img.channels() == 3) img.at<Vec3b>(j, i)[0] = 0; img.at<Vec3b>(j, i)[1] = 0; Java中apache下面FTPClient主动模式和被动模式 Caelebs: 奇怪啊,这样设置被动模式的端口范围之后,客户端传输文件的时候,netstat看到的端口里面还是不在服务端设置的端口范围里 Java中apache下面FTPClient主动模式和被动模式 xianer5221: 找了大半天就你这个有用