import java.io.File; |
002 | import java.io.FileInputStream; |
003 | import java.io.FileOutputStream; |
004 | import java.io.IOException; |
005 | import java.io.InputStream; |
006 | import java.io.OutputStream; |
007 | import java.io.PrintWriter; |
008 | import org.apache.commons.net.PrintCommandListener; |
009 | import org.apache.commons.net.ftp.FTP; |
010 | import org.apache.commons.net.ftp.FTPClient; |
011 | import org.apache.commons.net.ftp.FTPFile; |
012 | import org.apache.commons.net.ftp.FTPReply; |
013 | |
014 | public class ContinueFTP { |
015 | private FTPClient ftpClient = new FTPClient(); |
016 | |
017 | public ContinueFTP(){ |
018 | //设置将过程中使用到的命令输出到控制台 |
019 | this .ftpClient.addProtocolCommandListener( new PrintCommandListener( new PrintWriter(System.out))); |
020 | } |
021 | |
022 | /** |
023 | * java编程中用于连接到FTP服务器 |
024 | * @param hostname 主机名 |
025 | * @param port 端口 |
026 | * @param username 用户名 |
027 | * @param password 密码 |
028 | * @return 是否连接成功 |
029 | * @throws IOException |
030 | */ |
031 | public boolean connect(String hostname, int port,String username,String password) throws IOException{ |
032 | ftpClient.connect(hostname, port); |
033 | if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){ |
034 | if (ftpClient.login(username, password)){ |
035 | return true ; |
036 | } |
037 | } |
038 | disconnect(); |
039 | return false ; |
040 | } |
041 | |
042 | /** |
043 | * 从FTP服务器上下载文件 |
044 | * @param remote 远程文件路径 |
045 | * @param local 本地文件路径 |
046 | * @return 是否成功 |
047 | * @throws IOException |
048 | */ |
049 | public boolean download(String remote,String local) throws IOException{ |
050 | ftpClient.enterLocalPassiveMode(); |
051 | ftpClient.setFileType(FTP.BINARY_FILE_TYPE); |
052 | boolean result; |
053 | File f = new File(local); |
054 | FTPFile[] files = ftpClient.listFiles(remote); |
055 | if (files.length != 1 ){ |
056 | System.out.println( "远程文件不唯一" ); |
057 | return false ; |
058 | } |
059 | long lRemoteSize = files[ 0 ].getSize(); |
060 | if (f.exists()){ |
061 | OutputStream out = new FileOutputStream(f, true ); |
062 | System.out.println( "本地文件大小为:" +f.length()); |
063 | if (f.length() >= lRemoteSize){ |
064 | System.out.println( "本地文件大小大于远程文件大小,下载中止" ); |
065 | return false ; |
066 | } |
067 | ftpClient.setRestartOffset(f.length()); |
068 | result = ftpClient.retrieveFile(remote, out); |
069 | out.close(); |
070 | } else { |
071 | OutputStream out = new FileOutputStream(f); |
072 | result = ftpClient.retrieveFile(remote, out); |
073 | out.close(); |
074 | } |
075 | return result; |
076 | } |
077 | |
078 | /** |
079 | * 上传文件到FTP服务器,支持断点续传 |
080 | * @param local 本地文件名称,绝对路径 |
081 | * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构 |
082 | * @return 上传结果 |
083 | * @throws IOException |
084 | */ |
085 | public UploadStatus upload(String local,String remote) throws IOException{ |
086 | //设置PassiveMode传输 |
087 | ftpClient.enterLocalPassiveMode(); |
088 | //设置以二进制流的方式传输 |
089 | ftpClient.setFileType(FTP.BINARY_FILE_TYPE); |
090 | UploadStatus result; |
091 | //对远程目录的处理 |
092 | String remoteFileName = remote; |
093 | if (remote.contains( "/" )){ |
094 | remoteFileName = remote.substring(remote.lastIndexOf( "/" )+ 1 ); |
095 | String directory = remote.substring( 0 ,remote.lastIndexOf( "/" )+ 1 ); |
096 | if (!directory.equalsIgnoreCase( "/" )&&!ftpClient.changeWorkingDirectory(directory)){ |
097 | //如果远程目录不存在,则递归创建远程服务器目录 |
098 | int start= 0 ; |
099 | int end = 0 ; |
100 | if (directory.startsWith( "/" )){ |
101 | start = 1 ; |
102 | } else { |
103 | start = 0 ; |
104 | } |
105 | end = directory.indexOf( "/" ,start); |
106 | while ( true ){ |
107 | String subDirectory = remote.substring(start,end); |
108 | if (!ftpClient.changeWorkingDirectory(subDirectory)){ |
109 | if (ftpClient.makeDirectory(subDirectory)){ |
110 | ftpClient.changeWorkingDirectory(subDirectory); |
111 | } else { |
112 | System.out.println( "创建目录失败" ); |
113 | return UploadStatus.Create_Directory_Fail; |
114 | } |
115 | } |
116 | |
117 | start = end + 1 ; |
118 | end = directory.indexOf( "/" ,start); |
119 | |
120 | //检查所有目录是否创建完毕 |
121 | if (end <= start){ |
122 | break ; |
123 | } |
124 | } |
125 | } |
126 | } |
127 | |
128 | //检查远程是否存在文件 |
129 | FTPFile[] files = ftpClient.listFiles(remoteFileName); |
130 | if (files.length == 1 ){ |
131 | long remoteSize = files[ 0 ].getSize(); |
132 | File f = new File(local); |
133 | long localSize = f.length(); |
134 | if (remoteSize==localSize){ |
135 | return UploadStatus.File_Exits; |
136 | } else if (remoteSize > localSize){ |
137 | return UploadStatus.Remote_Bigger_Local; |
138 | } |
139 | |
140 | //尝试移动文件内读取指针,实现断点续传 |
141 | InputStream is = new FileInputStream(f); |
142 | if (is.skip(remoteSize)==remoteSize){ |
143 | ftpClient.setRestartOffset(remoteSize); |
144 | if (ftpClient.storeFile(remote, is)){ |
145 | return UploadStatus.Upload_From_Break_Success; |
146 | } |
147 | } |
148 | |
149 | //如果断点续传没有成功,则删除服务器上文件,重新上传 |
150 | if (!ftpClient.deleteFile(remoteFileName)){ |
151 | return UploadStatus.Delete_Remote_Faild; |
152 | } |
153 | is = new FileInputStream(f); |
154 | if (ftpClient.storeFile(remote, is)){ |
155 | result = UploadStatus.Upload_New_File_Success; |
156 | } else { |
157 | result = UploadStatus.Upload_New_File_Failed; |
158 | } |
159 | is.close(); |
160 | } else { |
161 | InputStream is = new FileInputStream(local); |
162 | if (ftpClient.storeFile(remoteFileName, is)){ |
163 | result = UploadStatus.Upload_New_File_Success; |
164 | } else { |
165 | result = UploadStatus.Upload_New_File_Failed; |
166 | } |
167 | is.close(); |
168 | } |
169 | return result; |
170 | } |
171 | /** |
172 | * 断开与远程服务器的连接 |
173 | * @throws IOException |
174 | */ |
175 | public void disconnect() throws IOException{ |
176 | if (ftpClient.isConnected()){ |
177 | ftpClient.disconnect(); |
178 | } |
179 | } |
180 | |
181 | public static void main(String[] args) { |
182 | ContinueFTP myFtp = new ContinueFTP(); |
183 | try { |
184 | myFtp.connect( "192.168.21.171" , 21 , "test" , "test" ); |
185 | System.out.println(myFtp.upload( "E://VP6.flv" , "/MIS/video/VP6.flv" )); |
186 | myFtp.disconnect(); |
187 | } catch (IOException e) { |
188 | System.out.println( "连接FTP出错:" +e.getMessage()); |
189 | } |
190 | } |
191 | } |