用代码打开FTP(2)
一、大数据量的ftp文件下载
1.通过socket获取ftp服务器链接,并读取文件列表到本地文件
public void getFTPSocket() { try { // server是ftp的ip,userName为登录名,passWord为密码 Socket socket = new Socket(server, 21); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); //接收初始链接信息 byte[] buffer = new byte[100]; int length = is.read(buffer); String s = new String(buffer, 0, length); System.out.println(s); //发送用户名 String str = "USER " + userName + "\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //发送密码 str = "PASS " + passWord + "\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //发送切换文件夹指令 str = "CWD " + path + "\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //进入被动模式 str = "PASV\r\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //得到被动监听信息 str = "EPSV\n"; os.write(str.getBytes()); //得到返回值 length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //取得FTP被动监听的端口号 String portlist=s.substring(s.indexOf("(|||")+4,s.indexOf("|)")); System.out.println(portlist); //设定传输方式为二进制方式 str = "TYPE I\n"; os.write(str.getBytes()); length = is.read(buffer); s = new String(buffer, 0, length); System.out.println(s); //实例化ShowList线程类,链接FTP被动监听端口号 scenicFlowList sl=new scenicFlowList(); sl.port=Integer.parseInt(portlist); sl.start(); // 读取文件列表 str = "LIST\n"; os.write(str.getBytes()); //关闭链接 is.close(); os.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } //得到被动链接信息类,这个类是多线程的 class scenicFlowList extends Thread{ public int port=0; byte[] buffer = new byte[100]; public void run(){ try{ Socket socket = new Socket(server,this.port); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); //将文件列表写入本地文件 writeToLocal(localPath,is); //关闭链接 is.close(); os.close(); socket.close(); } catch(Exception e){ } } } /** * 将InputStream写入本地文件 * @param destination 写入本地目录 * @param input 输入流 * @throws IOException */ private static void writeToLocal(String destination, InputStream input) throws IOException { int index; byte[] bytes = new byte[10240]; File file = new File(destination); if(file.exists()){ file.delete(); } file.createNewFile(); FileOutputStream downloadFile = new FileOutputStream(destination); while ((index = input.read(bytes)) != -1) { downloadFile.write(bytes, 0, index); downloadFile.flush(); } downloadFile.close(); input.close(); }
2.获取本地文件列表,读取文件内容
// 获取下载ftp文件列表 FileInputStream fileInputStream = new FileInputStream(localPath); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf8"); BufferedReader reader = new BufferedReader(inputStreamReader); String tempString = null; // 读取ftp文件列表每行文件名 while ((tempString = reader.readLine()) != null) { //从tempString中获取文件名fileName *****此处省略******* // 每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。 ftp.enterLocalPassiveMode(); // 从服务器上读取指定的文件内容 InputStream ins = ftp.retrieveFileStream(fileName); if (ins != null) { BufferedReader reader2 = new BufferedReader(new InputStreamReader(ins, "UTF-8")); String tempString2 = null; while ((tempString2 = reader2.readLine()) != null) { //对文件内容操作 *****此处省略****** } reader2.close(); ins.close(); ftp.completePendingCommand(); } }
二、分析读取ftp文件内容1.2方式
第一种方式(上篇内容),获取文件列表用 FTPFile[] fs = ftp.listFiles();列表量成千上万时,则该数组在内存中开辟大量空间,且循环数组效率低下。如果选择先存到本地
ftp.retrieveFile(ff.getName(), is); 再读取内容,效率更低。但是对于数据量不大的ftp文件,操作简单便利。
第二种方式(本篇内容),通过ftp命令读取文件列表 str = "LIST\n"; 列表再多都能在1s内读完并存储在本地,节约内存空间。且用输入流读取列表每行文件名,速度更快。
其次,ftp.retrieveFileStream(fileName);直接读取内容进行处理,避免再将内容写入本地再读的过多操作,节省时间。对于大数据量的ftp文件,效率更高。
浙公网安备 33010602011771号