getFileInputStream->FTP开始下载文件!"); FTPFile ftpFile = ftpClient.mlistFile(filePath);._451 anoth">
当前位置:   article > 正文

ftpClient.retrieveFileStream导致FTPClient后面操作失败_451 another command is currently pending

451 another command is currently pending
  1. public BufferedInputStream getFileInputStream(String filePath) {
  2. BufferedInputStream is = null;
  3. try {
  4. logger.debug("FtpUtils->getFileInputStream->FTP开始下载文件!");
  5. FTPFile ftpFile = ftpClient.mlistFile(filePath);
  6. if (null != ftpFile) {
  7. is = new BufferedInputStream(ftpClient.retrieveFileStream(filePath));
  8. } else {
  9. throw new BaseException("FtpUtils->getFileInputStream->找不到文件!");
  10. }
  11. logger.debug("FtpUtils->getFileInputStream->FTP下载文件成功!");
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. }
  15. return is;
  16. }

执行retrieveFileStream后执行FTPClient后面的操作如changeWorkingDirectory、listFiles会失败,在Debug时使用静态方法测试调用listFiles时出现以下错误,但程序正常运行时没有抛出异常,

  1. java.io.IOException: Unable to determine system type - response: 451 Another command is currently pending, please try again later.
  2. at org.apache.commons.net.ftp.FTPClient.getSystemType(FTPClient.java:2801)
  3. at org.apache.commons.net.ftp.FTPClient.__createParser(FTPClient.java:3369)
  4. at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3338)
  5. at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:3016)

 

原因:读完InputStream后必须在关闭它,如果不这样做,不关闭后续命令可能会意外地执行。要完成文件传输,必须调用completePendingCommand completePendingCommand和检查其返回值以验证是否成功。如果不这样做,后续命令可能会意外地执行。retrieveFileStream注释如下:
  1. /**
  2. * Returns an InputStream from which a named file from the server
  3. * can be read. If the current file type is ASCII, the returned
  4. * InputStream will convert line separators in the file to
  5. * the local representation. You must close the InputStream when you
  6. * finish reading from it. The InputStream itself will take care of
  7. * closing the parent data connection socket upon being closed.
  8. * <p>
  9. * <b>To finalize the file transfer you must call
  10. * {@link #completePendingCommand completePendingCommand } and
  11. * check its return value to verify success.</b>
  12. * If this is not done, subsequent commands may behave unexpectedly.
  13. * <p>
  14. * Note: if you have used {@link #setRestartOffset(long)},
  15. * the file data will start from the selected offset.
  16. *
  17. * @param remote The name of the remote file.
  18. * @return An InputStream from which the remote file can be read. If
  19. * the data connection cannot be opened (e.g., the file does not
  20. * exist), null is returned (in which case you may check the reply
  21. * code to determine the exact reason for failure).
  22. * @throws FTPConnectionClosedException
  23. * If the FTP server prematurely closes the connection as a result
  24. * of the client being idle or some other reason causing the server
  25. * to send FTP reply code 421. This exception may be caught either
  26. * as an IOException or independently as itself.
  27. * @throws IOException If an I/O error occurs while either sending a
  28. * command to the server or receiving a reply from the server.
  29. */
  30. public InputStream retrieveFileStream(String remote) throws IOException
  31. {
  32. return _retrieveFileStream(FTPCmd.RETR.getCommand(), remote);
  33. }

  1. /**
  2. * There are a few FTPClient methods that do not complete the
  3. * entire sequence of FTP commands to complete a transaction. These
  4. * commands require some action by the programmer after the reception
  5. * of a positive intermediate command. After the programmer's code
  6. * completes its actions, it must call this method to receive
  7. * the completion reply from the server and verify the success of the
  8. * entire transaction.
  9. * <p>
  10. * For example,
  11. * <pre>
  12. * InputStream input;
  13. * OutputStream output;
  14. * input = new FileInputStream("foobaz.txt");
  15. * output = ftp.storeFileStream("foobar.txt")
  16. * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
  17. * input.close();
  18. * output.close();
  19. * ftp.logout();
  20. * ftp.disconnect();
  21. * System.err.println("File transfer failed.");
  22. * System.exit(1);
  23. * }
  24. * Util.copyStream(input, output);
  25. * input.close();
  26. * output.close();
  27. * // Must call completePendingCommand() to finish command.
  28. * if(!ftp.completePendingCommand()) {
  29. * ftp.logout();
  30. * ftp.disconnect();
  31. * System.err.println("File transfer failed.");
  32. * System.exit(1);
  33. * }
  34. * </pre>
  35. *
  36. * @return True if successfully completed, false if not.
  37. * @throws FTPConnectionClosedException
  38. * If the FTP server prematurely closes the connection as a result
  39. * of the client being idle or some other reason causing the server
  40. * to send FTP reply code 421. This exception may be caught either
  41. * as an IOException or independently as itself.
  42. * @throws IOException If an I/O error occurs while either sending a
  43. * command to the server or receiving a reply from the server.
  44. */
  45. public boolean completePendingCommand() throws IOException
  46. {
  47. return FTPReply.isPositiveCompletion(getReply());
  48. }

解决方案:关闭流,调用completePendingCommand()方法

  1. InputStream in = ftpClient.retrieveFileStream(fileName);
  2. in.close();
  3. ftpClient.completePendingCommand();

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/255576
推荐阅读
相关标签
  

闽ICP备14008679号