apache fip 工具类

Java - Apache Mina 自定义协议通信 一、定义协议实体 import java.nio.charset.Charset; /** * 自定义协议的消息体 */ public class MyMsg { /** * 消息长度 */ private Integer lenth; /** * 发送人 */ private Long sender; /** * 接收人 */ p 阅读详情

package com.isoftstone.common.utils.ftp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ProtocolCommandListener;
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;

import com.isoftstone.common.utils.Configuration;

/**
 * 支持断点续传的FTP实用类
 *
 * @version 0.1 实现基本断点上传下载
 * @version 0.2 实现上传下载进度汇报
 * @version 0.3 实现中文目录创建及中文文件创建,添加对于中文的支持
 */
public class FTPTools {

 // 获取配置文件连接信息
 static FTPClient ftpClient = null;
 static String strServerip = ""; // FTP服务器IP
 static String strServeruser = ""; // FTP服务器帐号
 static String strServerpassword = ""; // FTP服务器密码
 static String strServerurl = ""; // FTP服务器根路径
 static int iServerport = 0; // FTP服务器端口

 static {
  /*-------------获取配置文件常量 start------------*/
  Configuration rc = new Configuration("config.properties");// 相对路径
  if (rc.getValue("serverip") != null
    && !"".equals(rc.getValue("serverip"))) {
   strServerip = rc.getValue("serverip");
  }
  if (rc.getValue("serveruser") != null
    && !"".equals(rc.getValue("serveruser"))) {
   strServeruser = rc.getValue("serveruser");
  }
  if (rc.getValue("serverpassword") != null
    && !"".equals(rc.getValue("serverpassword"))) {
   strServerpassword = rc.getValue("serverpassword");
  }
  if (rc.getValue("serverurl") != null
    && !"".equals(rc.getValue("serverurl"))) {
   strServerurl = rc.getValue("serverurl");
  }
  if (rc.getValue("serverport") != null
    && !"".equals(rc.getValue("serverport"))) {
   iServerport = Integer.parseInt(rc.getValue("serverport"));
  }
  /*-------------获取FTP连接   start------------*/

 }

 // 枚举类UploadStatus代码

 public enum UploadStatus {
  Create_Directory_Fail, // 远程服务器相应目录创建失败
  Create_Directory_Success, // 远程服务器创建目录成功
  Upload_New_File_Success, // 上传新文件成功
  Upload_New_File_Failed, // 上传新文件失败
  File_Exits, // 文件已经存在
  Remote_Bigger_Local, // 远程文件大于本地文件
  Upload_From_Break_Success, // 断点续传成功
  Upload_From_Break_Failed, // 断点续传失败
  Delete_Remote_Faild; // 删除远程文件失败
 }

 // 枚举类DownloadStatus代码
 public enum DownloadStatus {
  Remote_File_Noexist, // 远程文件不存在
  Local_Bigger_Remote, // 本地文件大于远程文件
  Download_From_Break_Success, // 断点下载文件成功
  Download_From_Break_Failed, // 断点下载文件失败
  Download_New_Success, // 全新下载文件成功
  Download_New_Failed; // 全新下载文件失败
 }
 /**
  *
  *
  * @Description: 设置编码
  *
  * @param code   
  * @return void    
  * @throws
  */
 public void setEncoding(String code) {
  ftpClient.setControlEncoding(code);
 }

 /**
  * 连接到FTP服务器
  *
  * @param hostname
  *            主机名
  * @param port
  *            端口
  * @param username
  *            用户名
  * @param password
  *            密码
  * @return 是否连接成功
  * @throws IOException
  */
 public static boolean connect(String encoding) throws IOException {
  if (ftpClient != null && ftpClient.isConnected())
   return false;
  ftpClient = new FTPClient();
  ftpClient.setControlEncoding(encoding);
  ftpClient.addProtocolCommandListener(new PrintCommandListener(
    new PrintWriter(System.out)));
  ftpClient.connect(strServerip, iServerport);
  if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
   if (ftpClient.login(strServeruser, strServerpassword)) {
    return true;
   }
  }
  disconnect();
  return false;
 }

  /**
   * 返回FTP目录下的文件列表
   * @param ftpDirectory
   * @return
   */
   public static List<String> getFileNameList(String ftpDirectory)
   {
      List<String> list = new ArrayList<String>();
      try 
      {
         FTPFile[] filenames =  ftpClient.listFiles(ftpDirectory);
         for(FTPFile fn : filenames){
          if (fn.isFile()) {
           list.add(fn.getName());
          }
         }
      }catch(Exception e){
         e.printStackTrace();
      }
      return list;
   } 
   /**
    *
    *
    * @Description: 删除文件夹
    *
    * @param path
    * @param isAll
    * @return
    * @throws IOException   
    * @return boolean    
    * @throws
    */
   public boolean removeDirectory(String path, boolean isAll)
   throws IOException {

    if (!isAll) {
    return removeDirectory(path);
    }
 
    FTPFile[] ftpFileArr = ftpClient.listFiles(path);
    if (ftpFileArr == null || ftpFileArr.length == 0) {
    return removeDirectory(path);
    }
    //
    for (FTPFile ftpFile : ftpFileArr) {
    String name = ftpFile.getName();
    if (ftpFile.isDirectory()) {
     System.out.println("* [sD]Delete subPath ["+path + "/" + name+"]");
     removeDirectory(path + "/" + name, true);
    } else if (ftpFile.isFile()) {
     System.out.println("* [sF]Delete file ["+path + "/" + name+"]");
     deleteFile(path + "/" + name);
    }
   }
   return ftpClient.removeDirectory(path);
   }

  
   /**
    *
    *
    * @Description: 删除FTP文件
    *
    * @param pathName
    * @return
    * @throws IOException   
    * @return boolean    
    * @throws
    */
   public static boolean deleteFile(String pathName) throws IOException {
    return ftpClient.deleteFile(pathName);
      }
  
 /**
  * 从FTP服务器上下载文件,支持断点续传,上传百分比汇报
  *
  * @param remote
  *            远程文件路径
  * @param local
  *            本地文件路径
  * @return 上传的状态
  * @throws IOException
  */
  public static DownloadStatus download(String remote, String local)
   throws IOException {
  // 设置被动模式
  ftpClient.enterLocalPassiveMode();
  // 设置以二进制方式传输
  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  DownloadStatus result;
  
  // 检查远程文件是否存在
  FTPFile[] files = ftpClient.listFiles(remote);
  if (files.length != 1) {
   System.out.println("远程文件不存在");
   return DownloadStatus.Remote_File_Noexist;
  }

  long lRemoteSize = files[0].getSize();
  File f = new File(local);
  // 本地存在文件,进行断点下载
  if (f.exists()) {
   long localSize = f.length();
   // 判断本地文件大小是否大于远程文件大小
   if (localSize >= lRemoteSize) {
    System.out.println("本地文件大于远程文件,下载中止");
    return DownloadStatus.Local_Bigger_Remote;
   }

   // 进行断点续传,并记录状态
   FileOutputStream out = new FileOutputStream(f, true);
   ftpClient.setRestartOffset(localSize);
   InputStream in = ftpClient.retrieveFileStream(remote);
   byte[] bytes = new byte[1024];
   long step = lRemoteSize / 100;
   long process = localSize / step;
   int c;
   while ((c = in.read(bytes)) != -1) {
    out.write(bytes, 0, c);
    localSize += c;
    long nowProcess = localSize / step;
    if (nowProcess > process) {
     process = nowProcess;
     if (process % 10 == 0)
      System.out.println("下载进度:" + process);
     // 更新文件下载进度,值存放在process变量中
    }
   }
   in.close();
   out.close();
   boolean isDo = ftpClient.completePendingCommand();
   if (isDo) {
    result = DownloadStatus.Download_From_Break_Success;
   } else {
    result = DownloadStatus.Download_From_Break_Failed;
   }
  } else {
   OutputStream out = new FileOutputStream(f);
   InputStream in = ftpClient.retrieveFileStream(remote);
   byte[] bytes = new byte[1024];
   long step = lRemoteSize / 100;
   long process = 0;
   long localSize = 0L;
   int c;
   while ((c = in.read(bytes)) != -1) {
    out.write(bytes, 0, c);
    localSize += c;
    long nowProcess = localSize / step;
    if (nowProcess > process) {
     process = nowProcess;
     if (process % 10 == 0)
      System.out.println("下载进度:" + process);
     // 更新文件下载进度,值存放在process变量中
    }
   }
   in.close();
   out.close();
   boolean upNewStatus = ftpClient.completePendingCommand();
   if (upNewStatus) {
    result = DownloadStatus.Download_New_Success;
   } else {
    result = DownloadStatus.Download_New_Failed;
   }
  }
  return result;
 }

 /**
  * 上传文件到FTP服务器,支持断点续传
  *
  * @param local
  *            本地文件名称,绝对路径
  * @param remote
  *            远程文件路径,使用/home/directory1/subdirectory/file.ext或是
  *            http://www.guihua.org /subdirectory/file.ext
  *            按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
  * @return 上传结果
  * @throws IOException
  */
 public static UploadStatus upload(String local, String remote)
   throws IOException {
  // 设置PassiveMode传输
  ftpClient.enterLocalPassiveMode();
  // 设置以二进制流的方式传输
  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  UploadStatus result;
  // 对远程目录的处理
  //String remoteFileName = remote;
  if (remote.contains(File.separator)) {
   //remoteFileName = remote.substring(remote.lastIndexOf(File.separator) + 1);
   // 创建服务器远程目录结构,创建失败直接返回
   if (CreateDirecroty(remote, ftpClient) == UploadStatus.Create_Directory_Fail) {
    return UploadStatus.Create_Directory_Fail;
   }
  }

  // 检查远程是否存在文件
//  FTPFile[] files = ftpClient.listFiles(new String(remoteFileName
//    .getBytes("GBK"), "iso-8859-1"));
  FTPFile[] files = ftpClient.listFiles(remote);
  File f =  new File(local);
  if (files.length == 1) {
   long remoteSize = files[0].getSize();
   
   long localSize = f.length();
   if (remoteSize == localSize) {
    return UploadStatus.File_Exits;
   } else if (remoteSize > localSize) {
    return UploadStatus.Remote_Bigger_Local;
   }

   // 尝试移动文件内读取指针,实现断点续传
   result = uploadFile(remote, f, ftpClient, remoteSize);

   // 如果断点续传没有成功,则删除服务器上文件,重新上传
   if (result == UploadStatus.Upload_From_Break_Failed) {
    if (!ftpClient.deleteFile(remote)) {
     return UploadStatus.Delete_Remote_Faild;
    }
    result = uploadFile(remote, f, ftpClient, 0);
   }
  } else {
   result = uploadFile(remote, f, ftpClient, 0);
  }
  return result;
 }

 /**
  * 断开与远程服务器的连接
  *
  * @throws IOException
  */
 public static void disconnect() {
  try {
   if (ftpClient.isConnected()) {
    ftpClient.disconnect();
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 /**
  * 递归创建远程服务器目录
  *
  * @param remote
  *            远程服务器文件绝对路径
  * @param ftpClient
  *            FTPClient 对象
  * @return 目录创建是否成功
  * @throws IOException
  */
 private static UploadStatus CreateDirecroty(String remote,
   FTPClient ftpClient) throws IOException {
  UploadStatus status = UploadStatus.Create_Directory_Success;
  String directory = remote.substring(0, remote.lastIndexOf(File.separator) + 1);
  if (!directory.equalsIgnoreCase(File.separator)
    && !ftpClient.changeWorkingDirectory(directory)) {
   // 如果远程目录不存在,则递归创建远程服务器目录
   int start = 0;
   int end = 0;
   if (directory.startsWith(File.separator)) {
    start = 1;
   } else {
    start = 0;
   }
   end = directory.indexOf(File.separator, start);
   while (true) {
    String subDirectory = remote.substring(start, end);
    if (!ftpClient.changeWorkingDirectory(File.separator+subDirectory)) {
     if (ftpClient.makeDirectory(subDirectory)) {
      ftpClient.changeWorkingDirectory(subDirectory);
     } else {
      System.out.println("创建目录失败");
      return UploadStatus.Create_Directory_Fail;
     }
    }

    start = end + 1;
    end = directory.indexOf(File.separator, start);

    // 检查所有目录是否创建完毕
    if (end <= start) {
     break;
    }
   }
  }
  return status;
 }

 /**
  * 上传文件到服务器,新上传和断点续传
  *
  * @param remoteFile
  *            远程文件名,在上传之前已经将服务器工作目录做了改变
  * @param localFile
  *            本地文件 File句柄,绝对路径
  * @param processStep
  *            需要显示的处理进度步进值
  * @param ftpClient
  *            FTPClient 引用
  * @return
  * @throws IOException
  */
 private static UploadStatus uploadFile(String remoteFile, File localFile,
   FTPClient ftpClient, long remoteSize) throws IOException {
  UploadStatus status;
  // 显示进度的上传
  long step = localFile.length() / 100;
  long process = 0;
  long localreadbytes = 0L;
  long localcount = 0L;
  RandomAccessFile raf = new RandomAccessFile(localFile, "r");
  OutputStream out = ftpClient.appendFileStream(remoteFile);
  // 断点续传
  if (remoteSize > 0) {
   ftpClient.setRestartOffset(remoteSize);
   process = remoteSize / step;
   raf.seek(remoteSize);
   localreadbytes = remoteSize;
  }
  byte[] bytes = new byte[1024];
  int c;
  while ((c = raf.read(bytes)) != -1) {
   out.write(bytes, 0, c);
   localreadbytes += c;
   localcount = (localreadbytes/100)*100;
   if (localcount / step != process) {
    process = localcount / step;
    System.out.println("上传进度:" + process);
    // 汇报上传状态
   }
  }
  out.flush();
  raf.close();
  out.close();
  boolean result = ftpClient.completePendingCommand();
  if (remoteSize > 0) {
   status = result ? UploadStatus.Upload_From_Break_Success
     : UploadStatus.Upload_From_Break_Failed;
  } else {
   status = result ? UploadStatus.Upload_New_File_Success
     : UploadStatus.Upload_New_File_Failed;
  }
  return status;
 }
 /**
  *
  *
  * @Description: 文件是否存着
  *
  * @param path
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */
 public static boolean existDirectory(String path) throws IOException {
  boolean flag = false;
  FTPFile[] ftpFileArr = ftpClient.listFiles(path);
  for (FTPFile ftpFile : ftpFileArr) {
  if (ftpFile.isDirectory()
  && ftpFile.getName().equalsIgnoreCase(path)) {
  flag = true;
  break;
  }
  }
  return flag;
 }
 
 /**
  *
  *
  * @Description: 改变工作目录
  *
  * @param path
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */
 public static boolean changeDirectory(String path) throws IOException {
  return ftpClient.changeWorkingDirectory(path);
 }
 /**
  *
  *
  * @Description: 创建目录
  *
  * @param pathName
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */
 public static boolean createDirectory(String pathName) throws IOException {
  return ftpClient.makeDirectory(pathName);
 }
 /**
  *
  *
  * @Description: 删除文件
  *
  * @param path
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */
 public static boolean removeDirectory(String path) throws IOException {
  return ftpClient.removeDirectory(path);
 }
 /**
  *
  *
  * @Description: 重命名
  *
  * @param from
  * @param to
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */
 public static boolean renameDirectory(String from,String to) throws IOException {
  return ftpClient.rename(from,to);
 }
 /**
  * 将路径和文件名拼接起来
  *
  * @param folderPath
  *            某一文件夹路径字符串,e.g. "c:\cs\" 或 "c:\cs"
  * @param fileName
  *            某一文件名字符串, e.g. "cs.txt"
  * @return 文件全路径的字符串
  */
 public static String makeFilePath(String folderPath, String fileName) {
  return folderPath.endsWith("\\") || folderPath.endsWith("/") ? folderPath
    + fileName
    : folderPath + File.separatorChar + fileName;
 }
 
 /**
  *
  *
  * @Description: 复制文件夹 (未调试通过)
  *
  * @param fileNameFrom
  * @param fileNameTo
  * @return   
  * @return boolean    
  * @throws
  */
 public static boolean copyDirectoryBug(String fileNameFrom, String fileNameTo) {
 
  try {
      // 设置PassiveMode传输
   ftpClient.enterLocalPassiveMode();
   // 设置以二进制流的方式传输
   ftpClient.setFileType(FTP.BINARY_FILE_TYPE, FTP.BINARY_FILE_TYPE);
   ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);         
  //createDirectory(fileNameTo); // 如果文件夹不存在 则建立新文件夹
  FTPFile[] ftpFileArr = ftpClient.listFiles(fileNameFrom);
  for (int i = 0; i < ftpFileArr.length; i++) {
   if (ftpFileArr[i].isFile()) {
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     ByteArrayInputStream is = null;
     try {
      if (ftpClient.retrieveFile(makeFilePath(fileNameFrom, ftpFileArr[i].getName()), bos)) {
       is = new ByteArrayInputStream(bos.toByteArray());
       bos.flush();
       if (ftpClient.storeFile(makeFilePath(fileNameTo, ftpFileArr[i].getName()), is)) {
        System.err.println("File OK.");
       }
      }else{
       return false;
      }
  
     } catch (Exception e) {
     e.getStackTrace();
     } finally {
      try {
       bos.close();
       if (is!=null) {
       is.close();
      }
      } catch (Exception e) {
       e.getStackTrace();
      }
     }
   } else if (ftpFileArr[i].isDirectory()) {// 如果是子文件夹
    copyDirectoryBug(fileNameFrom + '/' + ftpFileArr[i], fileNameTo + '/'
      + ftpFileArr[i]);
   }
  }
  } catch (Exception e) {
   e.printStackTrace();
   }
  return true;
 }
 /**
  *
  *
  * @Description: 复制文件
  *
  * <listeners>
  * <nio-listener name="other" port="2121">
  *     <ssl>
     *            <keystore file="./res/ftpserver.jks" password="password" />
     *        </ssl>
  * </nio-listener>
  * </listeners>
  *    
  * @return void    
  * @throws
  */
 public static void copyDirectory(){
  //设置端口 需要设置两个 并且需要修改ftp    ftpd-typical.xml 配置文件
  int port1 = 21, port2 = 2121;
  FTPClient ftp1, ftp2;
  ProtocolCommandListener listener;

  listener = new PrintCommandListener(new PrintWriter(System.out), true);
  ftp1 = new FTPClient();
  ftp1.setControlEncoding("UTF-8");
  ftp1.addProtocolCommandListener(listener);
  ftp2 = new FTPClient();
  ftp2.setControlEncoding("UTF-8");
  ftp2.addProtocolCommandListener(listener);
  String server1 = "10.10.87.162";
  try {
   int reply;

   if (port1 > 0) {
    ftp1.connect(server1, port1);
   } else {
    ftp1.connect(server1);
   }
   System.out.println("Connected to " + server1 + ".");

   reply = ftp1.getReplyCode();

   if (!FTPReply.isPositiveCompletion(reply)) {
    ftp1.disconnect();
    System.err.println("FTP server1 refused connection.");
    System.exit(1);
   }
  } catch (IOException e) {
   if (ftp1.isConnected()) {
    try {
     ftp1.disconnect();
    } catch (IOException f) {
     // do nothing
    }
   }
   System.err.println("Could not connect to server1.");
   e.printStackTrace();
   System.exit(1);
  }

  String server2 = "10.10.87.162";
  try {
   int reply;
   if (port2 > 0) {
    ftp2.connect(server2, port2);
   } else {
    ftp2.connect(server2);
   }
   System.out.println("Connected to " + server2 + ".");

   reply = ftp2.getReplyCode();

   if (!FTPReply.isPositiveCompletion(reply)) {
    ftp2.disconnect();
    System.err.println("FTP server2 refused connection.");
    System.exit(1);
   }
  } catch (IOException e) {
   if (ftp2.isConnected()) {
    try {
     ftp2.disconnect();
    } catch (IOException f) {
     // do nothing
    }
   }
   System.err.println("Could not connect to server2.");
   e.printStackTrace();
   System.exit(1);
  }

  __main: try {
   if (!ftp1.login("admin", "123456")) {
    System.err.println("Could not login to " + server1);
    break __main;
   }

   if (!ftp2.login("admin", "123456")) {
    System.err.println("Could not login to " + server2);
    break __main;
   }
   ftp1.setFileType(FTP.BINARY_FILE_TYPE);
   ftp2.setFileType(FTP.BINARY_FILE_TYPE);
   // Let's just assume success for now.
   ftp2.enterRemotePassiveMode();

   ftp1.enterRemoteActiveMode(
     InetAddress.getByName(ftp2.getPassiveHost()),
     ftp2.getPassivePort());

   if (ftp1.remoteRetrieve("/ebookcon/123456/1242397_115221077_2.jpg")
     && ftp2.remoteStore("/ebookcon/123456/bak/1242397_115221077_2.jpg")) {

    ftp1.completePendingCommand();
    ftp2.completePendingCommand();
   } else {
    System.err
      .println("Couldn't initiate transfer.  Check that filenames are valid.");
    break __main;
   }

  } catch (IOException e) {
   e.printStackTrace();
   System.exit(1);
  } finally {
   try {
    if (ftp1.isConnected()) {
     ftp1.logout();
     ftp1.disconnect();
    }
   } catch (IOException e) {
    // do nothing
   }

   try {
    if (ftp2.isConnected()) {
     ftp2.logout();
     ftp2.disconnect();
    }
   } catch (IOException e) {
    e.getStackTrace();
   }
  }
 }
 
 
 
 /**
  *
  *
  * @Description:  复制文件
  *
  * @param sourcePath
  * @param targetPath
  * @return
  * @throws IOException   
  * @return boolean    
  * @throws
  */ 
 public static void copyFile(String sourcePath,String targetPath) {
  try {
   ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
   ftpClient.enterLocalPassiveMode();
   // ftpClient.changeWorkingDirectory("ebookcon/123456");
   FTPFile[] ftpFiles = ftpClient.listFiles(sourcePath);

   for (FTPFile file : ftpFiles) {

    System.err.println(file.getType());
    InputStream inputStream = ftpClient.retrieveFileStream(sourcePath
      + file.getName());

    FileOutputStream ops = new FileOutputStream(new File("C:/"
      + file.getName()));
    ReadableByteChannel byteChannel = Channels
      .newChannel(inputStream);
    ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 10);

    FileChannel outChannel = ops.getChannel();
    int readSize = 0;
    int curSize = 0;
    while ((readSize = byteChannel.read(byteBuffer)) != -1) {
     curSize += readSize;
     byteBuffer.flip();
     outChannel.write(byteBuffer);
     byteBuffer.clear();
     System.err.println(curSize + "  :  " + readSize);
    }
    byteBuffer = null;
    ops.close();
    inputStream.close();
    if (!ftpClient.completePendingCommand()) {
     ftpClient.logout();
     ftpClient.disconnect();
     System.err.println("File transfer failed.");
     System.exit(1);
    }

   }

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 
 
 
 /**
  * 关闭输入流。
  *
  * @param is
  *            输入流,可以是null。
  */
 public static void closeInputStream(InputStream is) {
  if (is != null) {
   try {
    is.close();
   } catch (IOException e) {
   }
  }
 }

 public static void closeOutputStream(OutputStream fos) {
  if (fos != null) {
   try {
    fos.close();
   } catch (IOException e) {
   }
  }
 }
 
 public static void main(String[] args) {
  try {
   
   FTPTools.connect("UTF-8");
   FTPTools.copyDirectoryBug("\\ebookcon\\123456", "\\ebookcon\\bbbb");
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   FTPTools.disconnect();
  }
 }
 

}

Apache Mina 源码再读4 IoSession.write()源码剖析 Apache Mina IoSession.write(Object message) 写出数据流程小结: 1、Processor 线程首选轮询newSessions中每一个IoSession. 然后,把IoSession 放到IoService 的managedSessions中进行管理追踪。 2、当IoSession.write(Object message) 调用时,会创建一个WriteFuture 对象,并创建一个WriteRequest 对象,把这个对象增加到每一个IoSession关联的Wr 阅读详情

相关推荐

5. System Design 5.9. Building FIP images with support for Trusted Board Boot

此构建的结果将是 bl1.bin、fip.bin 和 fwu_fip.bin二进制文件。FIP 和 FWU_FIP都将包含与 选定的信任链。使用 mbed TLS 源代码将影响 TF-A 的许可 使用此库生成的二进制文件。也可以在输出构建目录中找到这些证书。要构建 FWU_FIP,平台所需的任何 FWU 图像都必须在 命令行。构建和安装非安全镜像和SCP FWU镜像(NS_BL1U, NS_BL2U 和 SCP_BL2U) 不在本文档的讨论范围之内。文档,了解相应的内容 要使用的 mbed TLS 版本。

baron-周贺贺-代码改变世界ctw 176

JDK6.0学习笔记(十九)FIP客户端

 /** * FIP客户端 * 类库 jftp.jar * 输入参数 FTP主机名或者IP地址、用户名、密码、待下载的远程文件名、待上传的本地文件名 * *///import net.sf.jftp.net.ConnectionHandler;//import net.sf.jftp.net.ConnectionListener;//import net.sf.jftp.net.DataConne

陌上尘的Java学习旅程 777

Flink从入门到精通100篇(二十一)-Apache Flink 与 Apache Hive 的集成

导读:随着 Flink 在流式计算的应用场景逐渐成熟和流行。如果 Flink 能同时把批量计算的应用场景处理好,就能减少用户在使用 Flink 的开发和维护成本,并且能够丰富 Flink 的生态。因为 SQL 是批计算比较常用的工具,所以 Flink 针对于批计算主要以 SQL 为主要接口。本次分享主要针对 Flink 对批处理的设计与 Hive 的集成。 主要分为下面三点展开: 设计架构 项目进展 性能测试 首先和大家分享一下 Flink 批处理的设计架构。 1.背.

wenyusuran的专栏 1257

fip服务器上传文件,往ftp服务器上传文件

package com.lxkj.ftp;public class Ftp {private String ipAddr;//ip地址private Integer port;//端口号private String userName;//用户名private String pwd;//密码private String path;//aaa路径public String getIpAddr() {r...

weixin_35917052的博客 360

ThinkPHP+Layui开发的ERP管理系统

ERP采购生产销售系统,一款基于ThinkPHP+Layui开发的ERP管理系统,帮助中小企业实现ERP管理规范化,此系统能为你解决五大方面的经营问题:1.采购管理 2.销售管理 3.仓库管理 4.资金管理 5.生产管理,适用于:服装鞋帽、化妆品、机械机电、家具装潢、建材行业、快销品、母婴用品、办公用品、汽配汽修、生鲜农贸、手机通讯、数码家电、医药用品、制造业、信息技术服务行业等。提供全部无加密服务端和前端源代码,独立部署,不受限制。

u011092458的博客 788

从零到英雄:Spring Boot 微服务架构全攻略

在数字化转型的时代,微服务架构已成为构建可扩展、高可用系统的首选方案。本文以“从零到英雄”为主题,详细指导读者使用Spring Boot快速构建微服务帝国。从基础环境搭建入手,逐步深入到服务发现、配置管理、负载均衡、断路器、API网关、安全认证、监控与部署等核心模块。通过大量代码示例和详细解释,包括中文注释,帮助初学者和中级开发者掌握Spring Boot的核心概念和技术实践。文章强调实际操作,涵盖RESTful API开发、数据库集成、容器化部署等内容,并讨论常见问题与优化策略。无论你是Java开发者还是

一个被知识诅咒的人 2700

Apache POI工作簿

Apache POI工作簿 此处的术语“Workbook”指的Microsoft Excel文件。本章完成后,您将能够创建新的工作簿,并可以使用Java程序打开现有工作簿。 此处的术语“Workbook”指的Microsoft Excel文件。本章完成后,您将能够创建新的工作簿,并可以使用Java程序打开现有工作簿。 创建空白工作簿 下面简单的程序来创建一个空白Microsoft Excel工作簿。 import java.io.*; import org.apache.poi.xssf.usermod

奔腾游子 316

PCIE配置和地址空间

来源:https://www.jianshu.com/p/574e9a2cbc4e 每个PCIe设备,有这么一段空间,Host软件可以读取它获得该设备的一些信息,也可以通过它来配置该设备,这段空间就叫做PCIe的配置空间。不同于每个设备的其它空间,PCIe设备的配置空间是协议规定好的,哪个地方放什么内容,都是有定义的。PCI或者PCI-X时代就有配置空间的概念,那时的配置空间如下: 图6.1 整个配置空间就是一系列寄存器的集合,其中Type 0是Endpoint的配置,Type 1是Brid.

qq_28643619的博客 4060

apache+http+服务器+2.4+文档,apache2.4安装说明详细文档

安装apache2.4.29#安装aprtar -zxvf apr-1.6.3.tar.gzcd apr-1.6.3./configure --prefix=/usr/local/apr && make -j 4 && make install#安装apr-utiltar -zxvf apr-util-1.6.1.tar.gzcd apr-util-1.6.1./c...

weixin_32631179的博客 443

YOLO26涨点改进 | 独家创新,细节涨点改进篇 | CVPR 2025顶会 | YOLO26引入Mona即插即用模块, 含MoCAA和DyTMona二次创新改进,含多种创新改进高效发论文

本文给大家介绍Mona即插即用模块, 含MoCAA和DyTMona二次创新模块优化YOLO26模型。YOLO26引入 Mona通过引入多尺度视觉友好型卷积滤波器(如3x3、5x5、7x7深度卷积)和可伸缩归一化层来优化适配器设计,以更好地处理视觉信号并调节输入特征分布。YOLO26引入Mona即插即用模块, 含MoCAA和DyTMona二次创新改进,含多种创新改进高效发论文。适合目标检测、图像分割、图像分类等所有CV任务通用即插即用模块。

Ai缝合怪、助力小伙伴高效发论文 240

get_ccopt系列命令介绍

get_ccopt_property:用来获取cts阶段,clock tree上所有的参数信息,可以通过get_ccopt_property –help *获取所有参数。get_ccopt_skew_group_delay:用来获取skew group的相关信息,可以通过筛选出特定条件下skew_group的参数,如skew_group下latency最长是多少;get_ccopt_clock_tree_source_groups:获取clock tree的source group名字;

芯冰乐 281

java 工作簿_Apache POI工作簿

本篇文章帮大家学习apache POI工作簿,包含了Apache POI工作簿使用方法、操作技巧、实例演示和注意事项,有一定的学习价值,大家可以用来参考。此处的术语“Workbook”指的Microsoft Excel文件。本章完成后,您将能够创建新的工作簿,并可以使用java程序打开现有工作簿。创建空白工作簿下面简单的程序来创建一个空白Microsoft Excel工作簿。importjava...

weixin_33332712的博客 181

分级 API Key 的使用案例

分级 API Key 的使用案例 1. 背景介绍 1.1 问题由来 随着网络服务的普及,API(Application Programming Interface,应用程序编程接口)成为了连接不同系统和应用的关键桥梁。API Key(API密钥)

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 1010

快速上手 Apache-POI【操作微软office,主要是excel】

快速理清 Apache-POI【操作微软office,主要是excel】 文章目录快速理清 Apache-POI【操作微软office,主要是excel】前言一、POI是什么?二、使用步骤1.核心组件介绍2.引入依赖3.核心类3.1 工作簿类 Workbook3.2 标签页类 Sheet3.3 行类 Row3.4 单元格类 Cell4. 读取和创建4.1 读取4.2 创建总结 前言 提示:需要对面向对象思想有一定了解。 一、POI是什么? Apache POI - the Java API for M

weixin_42045234的博客 554

电动汽车远程监控与诊断软件:BMW ConnectedDrive EV远程监控二次开发_7.数据安全与隐私保护

数据加密是保护数据安全的重要手段之一。在电动汽车远程监控与诊断软件中,加密技术可以确保数据在传输过程中的安全性和完整性。常见的加密技术包括对称加密和非对称加密。

zhubeibei168的博客 884

【txt文本加密】使用 cryptography 库实现加密和解密

cryptography 库是一个强大的 Python 库,用于实现加密和解密功能。它提供了各种加密算法,包括对称加密、非对称加密、哈希函数等。

📷 图像处理践行者 | 传统算法 · 深度学习 · 多模态 | 分享实战经验与技术洞见,探索从像素到智能的无限可能。 2667

引领移动开发新风向——Apache Cordova原生过渡插件

引领移动开发新风向——Apache Cordova原生过渡插件 在移动应用开发的领域里,用户体验是决定一款应用是否成功的关键因素之一。而动画和过渡效果,作为提升用户体验的重要环节,一直受到开发者们的高度重视。今天,我们要为大家推荐一个能够显著提升移动应用视觉体验的神器——Apache Cordova原生过渡插件。 项目介绍 Cordova-plugin-native-transitions 是一款...

gitblog_00008的博客 447

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Apache Flink 与 Apache Hive 的集成

分享嘉宾:李锐&王刚 @ 阿里巴巴编辑整理:于广超内容来源:FlinkForward ASIA出品平台:DataFun注:欢迎转载,转载请留言。导读:随着 Flink 在流式...

大数据星球-浪尖 613

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

org.apache.flink.client.program.ProgramInvocationException: Job failed

完整报错信息如下: scala> senv.execute() org.apache.flink.client.program.ProgramInvocationException: Job failed (JobID: 91b7cc8709adb0c4a65702d85a4d09ad) at org.apache.flink.client.deployment.ClusterClientJobClientAdapter.lambda$null$6(ClusterClientJobCl

微电子学与固体电子学-俞驰 7965

Apache MINA学习之路(4)

       查看 Mina 对 TextLineCodec 的实现源码会发现,根据换行符解码的消息 默认最大长度是 1024, 相当于缓冲区最大能存放 1K 的数据。所以使用时,建议调整参数为 2K;        根据我们自己定义的文本换行符及编码格式编解码, 则需要把它们作为参数传递给编解码器;完整代码如下: 解码器 import java.nio.charset.Characte...

gpair的博客 158

【POI】Apache POI工作簿(五)

此处的术语“Workbook”指的Microsoft Excel文件。本章完成后,您将能够创建新的工作簿,并可以使用Java程序打开现有工作簿。 创建空白工作簿 下面简单的程序来创建一个空白Microsoft Excel工作簿。 import java.io.*; import org.apache.poi.xssf.usermodel.*; public class CreateWorkB

LFSenior 312

使用shell脚本自动安装Apache2.4.35

安装环境Centos7,联网进行安装。脚本如下: #!/bin/bash[ $(id -u) != "0" ] && echo "error,not root user" && exit 1export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/bin:/usr/sbinwhich httpdif [ ...

weixin_33836223的博客 642

java mina长连接池_使用 Apache mina 建立长连接

由于业务需要,有一些实时性要求高的接口从无状态的 HTTP 连接切换到了长连接, 所以最近基于 Apache mina 来实现了长连接.主要说明一下 Android 客户端的实现.依赖对于 Android 客户端来说, 不需要引入太多的包.首先下载 mina, 目前我用的版本是 2.0.13, 解压后引入 mina-core-2.0.13.jar 包. 然后下载 slf4j-android包,引入...

weixin_34404599的博客 399

Apache MINA 基于UDP实例

1、基于UDP服务端 server NioDatagramAcceptor acceptor = new NioDatagramAcceptor(); acceptor.setHandler(new MemoryMonitorHandler(this)); DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); c

qyj415的专栏 1207

性能提升约7倍!Apache Flink 与 Apache Hive 的集成

导读:随着 Flink 在流式计算的应用场景逐渐成熟和流行,如果 Flink 能同时把批量计算的应用场景处理好,就能减少用户在使用 Flink 时开发和维护的成本,并且能够丰富 Flink 的生态。SQL 是批计算中比较常用的工具,所以 Flink 针对于批计算也以 SQL 为主要接口。本次分享主要介绍 Flink 对批处理的设计与 Hive 的集成。主要分为下面三点展开: 设计架构 项目进展...

阿里云云栖号 2055
上一篇: Commons-net FTPClient completePendingCommand()经常使程序死掉的原因分析以及解决方式
下一篇: json 工具类
lb8607
博客等级 码龄18年 17粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lb8607

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值