ftp+nginx builds a picture server, uploading FTP files can be uploaded to the server, but the file size is 0 bytes and the program will freeze after clicking the button

Recently, when using ftp to upload, there is a problem, uploading pictures keeps failing, after debugging with breakpoints, it is found that the program sometimes stops running when uploading. And the file can be transferred to the server, but the file size is 0 bytes and the program will freeze after clicking the button. After continuous debugging, I finally found the problem. Let's talk about the problem and the solution process.

Cause of the problem: It needs to be set before uploading in FTPUtils. The tool class code is as follows

package com.taotao.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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;
import org.apache.commons.net.ftp.FTPReply;

/**
 * ftp upload and download tool class
 * <p>Title: FtpUtil</p>
*/
public class FtpUtil {

	/**
	 * Description: Upload files to FTP server
	 * @param host FTP server hostname
	 * @param port FTP server port
	 * @param username FTP login account
	 * @param password FTP login password
	 * @param basePath FTP server base directory
	 * @param filePath FTP server file storage path. For example, it is stored by date: /2017/01/01. The path of the file is basePath+filePath
	 * @param filename The filename uploaded to the FTP server
	 * @param input input stream
	 * @return returns true on success, false otherwise
	 */  
	public static boolean uploadFile(String host, int port, String username, String password, String basePath,
			String filePath, String filename, InputStream input) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);// connect to FTP server
			// If the default port is used, you can use ftp.connect(host) to directly connect to the FTP server
			ftp.login(username, password);// login
			
			reply = ftp.getReplyCode ();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			// switch to upload directory
			if (!ftp.changeWorkingDirectory(basePath+filePath)) {
				//Create a directory if the directory does not exist
				String[] dirs = filePath.split("/");
				String tempPath = basePath;
				for (String dir : dirs) {
					if (null == dir || "".equals(dir)) continue;
					tempPath += "/" + dir;
					if (!ftp.changeWorkingDirectory(tempPath)) {
						if (!ftp.makeDirectory(tempPath)) {
							return result;
						} else {
							ftp.changeWorkingDirectory(tempPath);
						}
					}
				}
			}
			ftp.setControlEncoding("UTF-8");
			ftp.enterLocalPassiveMode();
			//Set the type of uploaded file to binary type
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			//upload files
			if (!ftp.storeFile(filename, input)) {
				return result;
			}
			input.close();
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace ();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	/**
	 * Description: Download file from FTP server
	 * @param host FTP server hostname
	 * @param port FTP server port
	 * @param username FTP login account
	 * @param password FTP login password
	 * @param remotePath relative path on FTP server
	 * @param fileName filename to download
	 * @param localPath The path to save to the local after downloading
	 * @return
	 */  
	public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
			String fileName, String localPath) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);
			// If the default port is used, you can use ftp.connect(host) to directly connect to the FTP server
			ftp.login(username, password);// login
			reply = ftp.getReplyCode ();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			ftp.changeWorkingDirectory(remotePath);// Transfer to the FTP server directory
			FTPFile[] fs = ftp.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getName().equals(fileName)) {
					File localFile = new File(localPath + "/" + ff.getName());

					OutputStream is = new FileOutputStream(localFile);
					ftp.retrieveFile(ff.getName(), is);
					is.close();
				}
			}

			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace ();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	public static void main(String[] args) {
		try {  
	        FileInputStream in=new FileInputStream(new File("F:\\aaa.jpg"));  
	        boolean flag = uploadFile("192.168.174.128", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images","/2015/01/21", "gaigeming.jpg", in);  
	        System.out.println(flag);  
	    } catch (FileNotFoundException e) {  
	        e.printStackTrace ();  
	    }  
	}
}

ftp.enterLocalPassiveMode();
//Set the type of uploaded file to binary type
ftp.setFileType(FTP.BINARY_FILE_TYPE);

You need to do such a setting before uploading:

ftp.enterLocalPassiveMode();

This method means that before each data connection, the ftp client tells the ftp server to open a port to transmit data. Why do you do this, because the ftp server may open different ports to transmit data each time, but on Linux or other servers, due to security restrictions, some ports may not be opened, so blocking occurs. OK, problem solved.

I found this sentence online, but it does solve the problem

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325411467&siteId=291194637