getFileInputStream->FTP开始下载文件!"); FTPFile ftpFile = ftpClient.mlistFile(filePath);._451 anoth">
赞
踩
- public BufferedInputStream getFileInputStream(String filePath) {
- BufferedInputStream is = null;
- try {
- logger.debug("FtpUtils->getFileInputStream->FTP开始下载文件!");
- FTPFile ftpFile = ftpClient.mlistFile(filePath);
- if (null != ftpFile) {
- is = new BufferedInputStream(ftpClient.retrieveFileStream(filePath));
- } else {
- throw new BaseException("FtpUtils->getFileInputStream->找不到文件!");
- }
- logger.debug("FtpUtils->getFileInputStream->FTP下载文件成功!");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return is;
- }
执行retrieveFileStream后执行FTPClient后面的操作如changeWorkingDirectory、listFiles会失败,在Debug时使用静态方法测试调用listFiles时出现以下错误,但程序正常运行时没有抛出异常,
- java.io.IOException: Unable to determine system type - response: 451 Another command is currently pending, please try again later.
- at org.apache.commons.net.ftp.FTPClient.getSystemType(FTPClient.java:2801)
- at org.apache.commons.net.ftp.FTPClient.__createParser(FTPClient.java:3369)
- at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3338)
- at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:3016)
原因:读完InputStream后必须在关闭它,如果不这样做,不关闭后续命令可能会意外地执行。要完成文件传输,必须调用completePendingCommand completePendingCommand和检查其返回值以验证是否成功。如果不这样做,后续命令可能会意外地执行。retrieveFileStream注释如下:
- /**
- * Returns an InputStream from which a named file from the server
- * can be read. If the current file type is ASCII, the returned
- * InputStream will convert line separators in the file to
- * the local representation. You must close the InputStream when you
- * finish reading from it. The InputStream itself will take care of
- * closing the parent data connection socket upon being closed.
- * <p>
- * <b>To finalize the file transfer you must call
- * {@link #completePendingCommand completePendingCommand } and
- * check its return value to verify success.</b>
- * If this is not done, subsequent commands may behave unexpectedly.
- * <p>
- * Note: if you have used {@link #setRestartOffset(long)},
- * the file data will start from the selected offset.
- *
- * @param remote The name of the remote file.
- * @return An InputStream from which the remote file can be read. If
- * the data connection cannot be opened (e.g., the file does not
- * exist), null is returned (in which case you may check the reply
- * code to determine the exact reason for failure).
- * @throws FTPConnectionClosedException
- * If the FTP server prematurely closes the connection as a result
- * of the client being idle or some other reason causing the server
- * to send FTP reply code 421. This exception may be caught either
- * as an IOException or independently as itself.
- * @throws IOException If an I/O error occurs while either sending a
- * command to the server or receiving a reply from the server.
- */
- public InputStream retrieveFileStream(String remote) throws IOException
- {
- return _retrieveFileStream(FTPCmd.RETR.getCommand(), remote);
- }
- /**
- * There are a few FTPClient methods that do not complete the
- * entire sequence of FTP commands to complete a transaction. These
- * commands require some action by the programmer after the reception
- * of a positive intermediate command. After the programmer's code
- * completes its actions, it must call this method to receive
- * the completion reply from the server and verify the success of the
- * entire transaction.
- * <p>
- * For example,
- * <pre>
- * InputStream input;
- * OutputStream output;
- * input = new FileInputStream("foobaz.txt");
- * output = ftp.storeFileStream("foobar.txt")
- * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
- * input.close();
- * output.close();
- * ftp.logout();
- * ftp.disconnect();
- * System.err.println("File transfer failed.");
- * System.exit(1);
- * }
- * Util.copyStream(input, output);
- * input.close();
- * output.close();
- * // Must call completePendingCommand() to finish command.
- * if(!ftp.completePendingCommand()) {
- * ftp.logout();
- * ftp.disconnect();
- * System.err.println("File transfer failed.");
- * System.exit(1);
- * }
- * </pre>
- *
- * @return True if successfully completed, false if not.
- * @throws FTPConnectionClosedException
- * If the FTP server prematurely closes the connection as a result
- * of the client being idle or some other reason causing the server
- * to send FTP reply code 421. This exception may be caught either
- * as an IOException or independently as itself.
- * @throws IOException If an I/O error occurs while either sending a
- * command to the server or receiving a reply from the server.
- */
- public boolean completePendingCommand() throws IOException
- {
- return FTPReply.isPositiveCompletion(getReply());
- }
解决方案:关闭流,调用completePendingCommand()方法
- InputStream in = ftpClient.retrieveFileStream(fileName);
- in.close();
- ftpClient.completePendingCommand();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。