我最近在做一个ftp的多线程下载的时候遇到了一个问题。
我的程序的原理是先获得文件的大小然后按照给定的线程数进行分块创建出每块从那个字节开始下载要下载多小字节等信息,然后开始多线程下载,每个线程从给定的点开始下载,我在每个线程开始点的时候出现了问题在调用了FTPClient.rest()方法后 调用ftpClient.retrieveFileStream();后获得的inputStream是null,造成了问题,请高手指教 import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.File;/**
* Created by IntelliJ IDEA.
* User: feihp
* Date: 2008-9-11
* Time: 9:27:02
* To change this template use File | Settings | File Templates.
*/
public class FtpDownload {
public static void main(String[] agrs) {
try {
int blockCount = 5;//分5个线程下载
String ip = "192.168.5.30";
int port = 21;
String username = "root";
String password = "qweasd123";
String remotePath = "/root/temp/";
String remoteFileName = "rebot.rmvb";
String localPath = "D:/testftp/remote/rebot.rmvb";
FtpDownload ftpDownload = new FtpDownload(ip, port, username, password, remotePath, remoteFileName, localPath);
long size = ftpDownload.size();//获得远程文件的大小
if (size == 0) {
return;
}
System.out.println("文件大小为 " + size + " B");
List blockList = ftpDownload.buildBlock(size, blockCount); //创建分块信息,5个线程分成5个块
if (blockList != null && blockList.size() > 0) {
for (int i = 0; i < blockList.size(); i++) {
FtpDownloadBlockInfo blockInfo = (FtpDownloadBlockInfo) blockList.get(i);
FtpDownloadThread ftpDownloadThread = new FtpDownloadThread(blockInfo);
ftpDownloadThread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String ip;//ip
private int port;//端口
private String username;
private String password;
private String remotePath;
private String remoteFileName;
private String localPath;
public FtpDownload(String ip, int port, String username, String password, String remotePath, String remoteFileName, String localPath) {
this.ip = ip;
this.port = port;
this.username = username;
this.password = password;
this.remotePath = remotePath;
this.remoteFileName = remoteFileName;
this.localPath = localPath;
}
private List buildBlock(long size, int blockCount) {
long blockSize = size / blockCount;
long lastSize = size % blockCount;
List blockList = new ArrayList();
for (int i = 0; i < blockCount; i++) {
long beginPoint = i * blockSize;
long endPoint = i * blockSize + blockSize;
if (blockCount == (i + 1)) {
endPoint = endPoint + lastSize;
blockSize = blockSize + lastSize;
}
FtpDownloadBlockInfo blockInfo = new FtpDownloadBlockInfo(blockSize, beginPoint, localPath, ip,
remotePath + remoteFileName, username, password, port);
blockList.add(blockInfo);
}
return blockList;
}
private long size() {
long size = 0;
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.connect(ip, port);
ftpClient.login(username, password);
FTPFile[] files = ftpClient.listFiles(remotePath);
for (int i = 0; i < files.length; i++) {
FTPFile file = files[i];
String fileName = file.getName();
if (fileName.equals(remoteFileName)) {
size = file.getSize();
return size;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return size;
}
}
我的程序的原理是先获得文件的大小然后按照给定的线程数进行分块创建出每块从那个字节开始下载要下载多小字节等信息,然后开始多线程下载,每个线程从给定的点开始下载,我在每个线程开始点的时候出现了问题在调用了FTPClient.rest()方法后 调用ftpClient.retrieveFileStream();后获得的inputStream是null,造成了问题,请高手指教 import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.File;/**
* Created by IntelliJ IDEA.
* User: feihp
* Date: 2008-9-11
* Time: 9:27:02
* To change this template use File | Settings | File Templates.
*/
public class FtpDownload {
public static void main(String[] agrs) {
try {
int blockCount = 5;//分5个线程下载
String ip = "192.168.5.30";
int port = 21;
String username = "root";
String password = "qweasd123";
String remotePath = "/root/temp/";
String remoteFileName = "rebot.rmvb";
String localPath = "D:/testftp/remote/rebot.rmvb";
FtpDownload ftpDownload = new FtpDownload(ip, port, username, password, remotePath, remoteFileName, localPath);
long size = ftpDownload.size();//获得远程文件的大小
if (size == 0) {
return;
}
System.out.println("文件大小为 " + size + " B");
List blockList = ftpDownload.buildBlock(size, blockCount); //创建分块信息,5个线程分成5个块
if (blockList != null && blockList.size() > 0) {
for (int i = 0; i < blockList.size(); i++) {
FtpDownloadBlockInfo blockInfo = (FtpDownloadBlockInfo) blockList.get(i);
FtpDownloadThread ftpDownloadThread = new FtpDownloadThread(blockInfo);
ftpDownloadThread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String ip;//ip
private int port;//端口
private String username;
private String password;
private String remotePath;
private String remoteFileName;
private String localPath;
public FtpDownload(String ip, int port, String username, String password, String remotePath, String remoteFileName, String localPath) {
this.ip = ip;
this.port = port;
this.username = username;
this.password = password;
this.remotePath = remotePath;
this.remoteFileName = remoteFileName;
this.localPath = localPath;
}
private List buildBlock(long size, int blockCount) {
long blockSize = size / blockCount;
long lastSize = size % blockCount;
List blockList = new ArrayList();
for (int i = 0; i < blockCount; i++) {
long beginPoint = i * blockSize;
long endPoint = i * blockSize + blockSize;
if (blockCount == (i + 1)) {
endPoint = endPoint + lastSize;
blockSize = blockSize + lastSize;
}
FtpDownloadBlockInfo blockInfo = new FtpDownloadBlockInfo(blockSize, beginPoint, localPath, ip,
remotePath + remoteFileName, username, password, port);
blockList.add(blockInfo);
}
return blockList;
}
private long size() {
long size = 0;
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.connect(ip, port);
ftpClient.login(username, password);
FTPFile[] files = ftpClient.listFiles(remotePath);
for (int i = 0; i < files.length; i++) {
FTPFile file = files[i];
String fileName = file.getName();
if (fileName.equals(remoteFileName)) {
size = file.getSize();
return size;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return size;
}
}
解决方案 »
- 新手学习java中关于ArrayList,LinkedList,HashSet,Vector,TreeSet的区别和使用
- 关于j2se中配置文件的应用,及反射的一些含义,和普通new一个对象有什么显著的区别?
- 新手代码问题 请教高手指教
- 有人会swt这个插件吗 用过的过来下 有分相送
- 十万火急,请高手帮忙,在线等!在搞不出来,老板就要炒我尤鱼了!
- 请教各位高手
- 在asp.net环境下,调用applet.二者之间如何传递参数呢?
- 如何创建清晰度较高的缩略图片?
- 我的jtable中显示不出来,急呀!!帮帮忙看看???
- 想通过一例子彻底的弄懂java.io包中的类,真诚的希望高手给予帮助!
- 图像二进制文件的读取与图像文件的转换
- 一道java面试题,有点迷糊
public class FtpDownloadThread extends Thread {
private FtpDownloadBlockInfo blockInfo;
public FtpDownloadThread(FtpDownloadBlockInfo blockInfo) {
this.blockInfo = blockInfo;
}
public void run() {
System.out.println("begin download beginPoint:" + blockInfo.getBeginPoint() + " blockSize:" + blockInfo.getBlockSize());
long start = System.currentTimeMillis();
FTPClient ftpClient = null;
InputStream inputStream = null;
RandomAccessFile raf = null;
try {
ftpClient = new FTPClient();
ftpClient.connect(blockInfo.getIp(), blockInfo.getPort());
ftpClient.login(blockInfo.getUsername(), blockInfo.getPassword());
ftpClient.changeWorkingDirectory(blockInfo.getPath());
ftpClient.rest(String.valueOf(blockInfo.getBeginPoint()));//设置开始点偏移量
inputStream = ftpClient.retrieveFileStream(blockInfo.getPath());//此处由于设置了偏移量了 ,inputStream变成了null造成异常
raf = new RandomAccessFile(new File(blockInfo.getLocalPath()), "rw");
raf.seek(blockInfo.getBeginPoint());
this.downloadStream(inputStream,raf);
long end = System.currentTimeMillis();
System.out.println("end download beginPoint:"+blockInfo.getBeginPoint()+" blockSize:"+blockInfo.getBlockSize()+"->"+((end-start)/1000)+"s");
} catch (IOException e) {
System.out.println("end download failed beginPoint:"+blockInfo.getBeginPoint()+" blockSize:"+blockInfo.getBlockSize());
e.printStackTrace();
} finally {
try {
raf.close();
ftpClient.logout();
ftpClient.disconnect();
ftpClient = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void downloadStream(InputStream inputStream, RandomAccessFile raf) throws IOException {
long bloackSize = blockInfo.getBlockSize();
byte[] buffer = new byte[1024];
long bytesRead;
long downloaded = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
downloaded = downloaded + bytesRead;
if (downloaded > bloackSize) {
bytesRead = bytesRead - (downloaded - bloackSize);
}
raf.write(buffer, 0, (int) bytesRead);
if (downloaded > bloackSize) {
break;
}
}
raf.close();
inputStream.close();
}
}
public class FtpDownloadBlockInfo {
private long blockSize;
private long beginPoint;
private String localPath;
private String ip;
private String path;
private String username;
private String password;
private int port;
public FtpDownloadBlockInfo(long blockSize, long beginPoint, String localPath, String ip, String path,
String username, String password, int port) {
this.blockSize = blockSize;
this.beginPoint = beginPoint;
this.localPath = localPath;
this.ip = ip;
this.path = path;
this.username = username;
this.password = password;
this.port = port;
}
public long getBlockSize() {
return blockSize;
}
public long getBeginPoint() {
return beginPoint;
}
public String getLocalPath() {
return localPath;
}
public String getIp() {
return ip;
}
public String getPath() {
return path;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public int getPort() {
return port;
}
}
blockInfo.getPath()应该是文件名,不包括路径吧.但你传的参数里面好像有路径FtpDownloadBlockInfo blockInfo = new FtpDownloadBlockInfo(blockSize, beginPoint, localPath, ip,
remotePath + remoteFileName, username, password, port);我也是刚刚接触.....