2008-09-22

Java 获取FTP文件大小

使用 sun.net.ftp.FtpClient。


package h.davy;

import h.davy.ftp.FtpFileInfo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import sun.net.TelnetInputStream;
import sun.net.ftp.FtpClient;

public class Test {

private static int test() {
FtpClient ftp = null;
try {
ftp = new FtpClient();
ftp.openServer("192.168.1.27");
ftp.login("t01", "12345");
// ftp.login("anonymous", "anonymous@do.c");

System.out.println(ftp.pwd()); // 当前目录
System.out.println(ftp.system());

System.out.println("===============================");
ftp.ascii();
// 获取目录文件列表详细信息
TelnetInputStream listStream = ftp.list();
byte[] buf = new byte[2048];
int n = 0;
while (true) {
if (0 > (n = listStream.read(buf, 0, buf.length)))
break;
System.out.println(n);
String fileName = new String(buf, 0, n);
System.out.println(fileName);
}
listStream.close(); // 需要这个关闭流

System.out.println("===============================");
getFilesInfo(ftp, "/");
System.out.println("===============================");
System.out.println(getFileSize(ftp, "/test.tar.bz2"));
System.out.println(getFileSize(ftp, "/phpMyAdmin/index.php"));
System.out.println("===============================");
getFilesInfo(ftp, "/phpMyAdmin");
// 退出登录
ftp.sendServer("QUIT\r\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
// try {
// ftp.closeServer();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
return -1;
}

/**
* 获取某文件大小
*
* @param ftp
* @param filePath
* @return
* @throws IOException
*/
static long getFileSize(FtpClient ftp, String filePath) throws IOException {
ftp.binary(); // 需要切换到 Binary 模式
ftp.sendServer(String.format("SIZE %s\r\n", filePath));
StringBuffer sb = new StringBuffer();
while (true) {
int c = ftp.serverInput.read();
char ch = (char) c;
if (c < 0 || ch == '\n') { // end of stream || end of line
StringTokenizer tk = new StringTokenizer(sb.toString());
int index = 0;
while (tk.hasMoreTokens()) {
String token = tk.nextToken();
if (index == 1) {
try {
return Long.parseLong(token);
} catch (NumberFormatException e) {
return -1L;
}
}
index++;
}
}
if (ch == '\n')
continue;
else if (c <= 0)
break;
sb.append(ch);
}
return -1L;
}

/**
* 获取某目录中的所有文件
*
* @param ftp
* @param path
* @return
* @throws IOException
*/
static List<FtpFileInfo> getFilesInfo(FtpClient ftp, String path)
throws IOException {
List<FtpFileInfo> ret = new ArrayList<FtpFileInfo>();

ftp.cd(path); // 切换到指定目录
ftp.ascii(); // 需要切换到 ASCII 模式
TelnetInputStream listStream = ftp.list();
StringBuffer sb = new StringBuffer();
while (true) {
int c = listStream.read();
char ch = (char) c;
if (c < 0 || ch == '\n') { // end of stream || end of line
FtpFileInfo ffi = new FtpFileInfo();
StringTokenizer tk = new StringTokenizer(sb.toString());
int index = 0;
while (tk.hasMoreTokens()) {
String token = tk.nextToken();
switch (index) {
case 0: // file attribute string
// 这里可以根据 attribute string 分析该文件是否为目录。
// (若为目录第一个字符为"d")
ffi.setAttributeStr(token);
break;
case 1: // ??
break;
case 2: // owner
break;
case 3: // group
break;
case 4: // file size
try {
ffi.setFileSize(Long.parseLong(token));
} catch (NumberFormatException e) {
e.printStackTrace();
}
break;
case 5: // month
case 6: // day
case 7: // time
break;
case 8: // file name
ffi.setFileName(token);
break;
}
index++;
}
ret.add(ffi);
sb.setLength(0);
}
if (ch == '\n') {
continue;
} else if (c <= 0)
break;
sb.append(ch);
}
listStream.close(); // 需要这个关闭流
return ret;
}

/**
* @param args
*/
public static void main(String[] args) {
System.out.println(test());
}

}


注:其中的 FtpFileInfo 仅仅是个人定义的一个 Java Bean 没什么实质的内容。

注:对于 ftp.list() 打开的流需要关闭,要不然后续读取操作会被挂起。


//EOF

0 comments: