<code>001.</code><code>//使用sun的ftpclient做ftp上传下载</code>
<code>002.</code><code>import</code> <code>sun.net.*;</code>
<code>003.</code><code>import</code> <code>sun.net.ftp.*;</code>
<code>004.</code><code>import</code> <code>java.io.*;</code>
<code>005.</code><code>import</code> <code>java.util.*;</code>
<code>006.</code><code>/**</code>
<code>007.</code><code>ftp远程命令列表<br></code>
<code>008.</code><code>user port retr allo dele site xmkd cdup feat<br></code>
<code>009.</code><code>pass pasv stor rest cwd stat rmd xcup opts<br></code>
<code>010.</code><code>acct type appe rnfr xcwd help xrmd stou auth<br></code>
<code>011.</code><code>rein stru smnt rnto list noop pwd size pbsz<br></code>
<code>012.</code><code>quit mode syst abor nlst mkd xpwd mdtm prot<br></code>
<code>013.</code><code>在服务器上执行命令,如果用sendserver来执行远程命令(不能执行本地ftp命令)的话,所有ftp命令都要加上\r\n<br></code>
<code>014.</code><code>ftpclient.sendserver("xmkd /test/bb\r\n"); //执行服务器上的ftp命令<br></code>
<code>015.</code><code>ftpclient.readserverresponse一定要在sendserver后调用<br></code>
<code>016.</code><code>namelist("/test")获取指目录下的文件列表<br></code>
<code>017.</code><code>xmkd建立目录,当目录存在的情况下再次创建目录时报错<br></code>
<code>018.</code><code>xrmd删除目录<br></code>
<code>019.</code><code>dele删除文件<br></code>
<code>020.</code><code>* 针对ftp中的所有调用使用到文件名的地方请使用完整的路径名(绝对路径开始)。</code>
<code>021.</code><code>*/</code>
<code>022.</code>
<code>023.</code><code>public</code> <code>class</code> <code>ftputils {</code>
<code>024.</code><code>private</code> <code>ftpclient ftpclient;</code>
<code>025.</code><code>private</code> <code>string ipaddress;</code>
<code>026.</code><code>private</code> <code>int</code> <code>port;</code>
<code>027.</code><code>private</code> <code>string username;</code>
<code>029.</code><code>/**</code>
<code>030.</code><code>* 构造函数</code>
<code>031.</code><code>* @param ip string 机器ip</code>
<code>032.</code><code>* @param port string 机器ftp端口号</code>
<code>033.</code><code>* @param username string ftp用户名</code>
<code>035.</code><code>* @throws exception</code>
<code>036.</code><code>*/</code>
<code>037.</code><code>public</code> <code>ftputils(string ip, </code><code>int</code> <code>port, string username, string password) </code><code>throws</code>
<code>038.</code><code>exception {</code>
<code>039.</code><code>this</code><code>.ipaddress = ip;</code>
<code>040.</code><code>this</code><code>.port = port;</code>
<code>041.</code><code>this</code><code>.ftpclient = </code><code>new</code> <code>ftpclient(ipaddress, port);</code>
<code>042.</code><code>this</code><code>.username = username;</code>
<code>043.</code><code>this</code><code>.password = password;</code>
<code>044.</code><code>}</code>
<code>045.</code><code>/**</code>
<code>046.</code><code>* 构造函数</code>
<code>047.</code><code>* @param ip string 机器ip,默认端口为21</code>
<code>048.</code><code>* @param username string ftp用户名</code>
<code>049.</code><code>* @param password string ftp密码</code>
<code>050.</code><code>* @throws exception</code>
<code>051.</code><code>*/</code>
<code>052.</code><code>public</code> <code>ftputils(string ip, string username, string password) </code><code>throws</code>
<code>053.</code><code>exception {</code>
<code>054.</code><code>this</code><code>(ip,</code><code>21</code><code>,username,password);</code>
<code>055.</code><code>}</code>
<code>056.</code><code>/**</code>
<code>057.</code><code>* 登录ftp服务器</code>
<code>058.</code><code>* @throws exception</code>
<code>059.</code><code>*/</code>
<code>060.</code><code>public</code> <code>void</code> <code>login() </code><code>throws</code> <code>exception {</code>
<code>061.</code><code>ftpclient.login(username, password);</code>
<code>062.</code><code>}</code>
<code>063.</code>
<code>064.</code><code>/**</code>
<code>065.</code><code>* 退出ftp服务器</code>
<code>066.</code><code>* @throws exception</code>
<code>067.</code><code>*/</code>
<code>068.</code><code>public</code> <code>void</code> <code>logout() </code><code>throws</code> <code>exception {</code>
<code>069.</code><code>//用ftpclient.closeserver()断开ftp出错时用下更语句退出</code>
<code>070.</code><code>ftpclient.sendserver(</code><code>"quit\r\n"</code><code>);</code>
<code>071.</code><code>int</code> <code>reply = ftpclient.readserverresponse(); </code><code>//取得服务器的返回信息</code>
<code>072.</code><code>}</code>
<code>073.</code><code>/**</code>
<code>074.</code><code>* 取得指定目录下的所有文件名,不包括目录名称</code>
<code>075.</code><code>* 分析namelist得到的输入流中的数,得到指定目录下的所有文件名</code>
<code>076.</code><code>* @param fullpath string</code>
<code>077.</code><code>* @return arraylist</code>
<code>078.</code><code>* @throws exception</code>
<code>079.</code><code>*/</code>
<code>080.</code><code>public</code> <code>arraylist filenames(string fullpath) </code><code>throws</code> <code>exception {</code>
<code>081.</code><code>ftpclient.ascii(); </code><code>//注意,使用字符模式</code>
<code>082.</code><code>telnetinputstream list = ftpclient.namelist(fullpath);</code>
<code>083.</code><code>byte</code><code>[] names = </code><code>new</code> <code>byte</code><code>[</code><code>2048</code><code>];</code><code>//如果文件数目很多,有可能溢出</code>
<code>084.</code><code>int</code> <code>bufsize = </code><code>0</code><code>;</code>
<code>085.</code><code>bufsize = list.read(names, </code><code>0</code><code>, names.length); </code><code>//从流中读取</code>
<code>086.</code><code>list.close();</code>
<code>087.</code><code>arraylist nameslist = </code><code>new</code> <code>arraylist();</code>
<code>088.</code><code>int</code> <code>i = </code><code>0</code><code>;</code>
<code>089.</code><code>int</code> <code>j = </code><code>0</code><code>;</code>
<code>090.</code><code>while</code> <code>(i < bufsize ) {</code>
<code>091.</code><code>if</code> <code>(names[i] == </code><code>10</code><code>) { </code><code>//字符模式为10,二进制模式为13</code>
<code>092.</code><code>string tempname = </code><code>new</code> <code>string(names, j, i - j);</code>
<code>093.</code><code>nameslist.add(tempname);</code>
<code>094.</code><code>//j = i + 2; //上一次位置二进制模式</code>
<code>095.</code><code>j = i + </code><code>1</code><code>; </code><code>//上一次位置字符模式</code>
<code>096.</code><code>}</code>
<code>097.</code><code>i = i + </code><code>1</code><code>;</code>
<code>098.</code><code>}</code>
<code>099.</code><code>return</code> <code>nameslist;</code>
<code>100.</code><code>}</code>
<code>101.</code><code>/**</code>
<code>102.</code><code>* 在ftp服务器上建立指定的目录,当目录已经存在的情下不会影响目录下的文件,这样用以判断ftp</code>
<code>103.</code><code>* 上传文件时保证目录的存在目录格式必须以"/"根目录开头</code>
<code>104.</code><code>* @param pathlist string</code>
<code>105.</code><code>* @throws exception</code>
<code>106.</code><code>*/</code>
<code>107.</code><code>public</code> <code>void</code> <code>buildremotedir(string pathlist) </code><code>throws</code> <code>exception {</code>
<code>108.</code><code>ftpclient.ascii();</code>
<code>109.</code><code>stringtokenizer s = </code><code>new</code> <code>stringtokenizer(pathlist, </code><code>"/"</code><code>); </code><code>//sign</code>
<code>110.</code><code>int</code> <code>count = s.counttokens();</code>
<code>111.</code><code>string pathname = </code><code>""</code><code>;</code>
<code>112.</code><code>while</code> <code>(s.hasmoreelements()) {</code>
<code>113.</code><code>pathname = pathname + </code><code>"/"</code> <code>+ (string) s.nextelement();</code>
<code>114.</code><code>try</code> <code>{</code>
<code>115.</code><code>ftpclient.sendserver(</code><code>"xmkd "</code> <code>+ pathname + </code><code>"\r\n"</code><code>);</code>
<code>116.</code><code>} </code><code>catch</code> <code>(exception e) {</code>
<code>117.</code><code>e = </code><code>null</code><code>;</code>
<code>118.</code><code>}</code>
<code>119.</code><code>int</code> <code>reply = ftpclient.readserverresponse();</code>
<code>120.</code><code>}</code>
<code>121.</code><code>ftpclient.binary();</code>
<code>122.</code><code>}</code>
<code>123.</code><code>/**</code>
<code>124.</code><code>* 上传文件到ftp服务器,remote路径以ftp服务器的"/"开始,带文件名、</code>
<code>125.</code><code>* 上传文件只能使用二进制模式,当文件存在时再次上传则会覆盖</code>
<code>126.</code><code>* @param local string</code>
<code>127.</code><code>* @param remote string</code>
<code>128.</code><code>* @throws exception</code>
<code>129.</code><code>*/</code>
<code>130.</code><code>public</code> <code>void</code> <code>upfile(string local, string remote) </code><code>throws</code> <code>exception {</code>
<code>131.</code><code>buildremotedir(remote.substring(</code><code>0</code><code>, remote.lastindexof(</code><code>"/"</code><code>)));</code>
<code>132.</code><code>ftpclient.binary(); </code><code>//此行代码必须放在buildremotedir之后</code>
<code>133.</code><code>telnetoutputstream ftpout = ftpclient.put(remote);</code>
<code>134.</code><code>inputstream in = </code><code>new</code> <code>fileinputstream(local);</code><code>//</code>
<code>135.</code><code>byte</code><code>[] buf = </code><code>new</code> <code>byte</code><code>[</code><code>204800</code><code>];</code>
<code>136.</code><code>int</code> <code>bufsize = </code><code>0</code><code>;</code>
<code>137.</code><code>while</code><code>((bufsize = in.read(buf, </code><code>0</code><code>, buf.length)) != -</code><code>1</code><code>){</code>
<code>138.</code><code>ftpout.write(buf, </code><code>0</code><code>, bufsize);</code>
<code>139.</code><code>}</code>
<code>140.</code><code>in.close();</code>
<code>141.</code><code>ftpout.close();</code>
<code>142.</code><code>}</code>
<code>143.</code><code>public</code> <code>void</code> <code>buildlocaldir(string fullpath) </code><code>throws</code> <code>exception {</code>
<code>144.</code>
<code>145.</code><code>if</code><code>(fullpath.lastindexof(</code><code>"/"</code><code>)<=</code><code>0</code><code>)</code><code>return</code><code>;</code>
<code>146.</code><code>string path=fullpath.substring(</code><code>0</code><code>,fullpath.lastindexof(</code><code>"/"</code><code>));</code>
<code>147.</code>
<code>148.</code><code>file f= </code><code>new</code> <code>file(path);</code>
<code>149.</code><code>if</code><code>(!f.exists()){</code>
<code>150.</code><code>f.mkdirs();</code>
<code>151.</code><code>}</code>
<code>152.</code><code>}</code>
<code>153.</code><code>public</code> <code>void</code> <code>downfile(string remote,string local) </code><code>throws</code> <code>exception {</code>
<code>154.</code><code>buildlocaldir(local);</code>
<code>155.</code><code>ftpclient.binary(); </code><code>//此行代码必须放在buildremotedir之后</code>
<code>156.</code><code>outputstream out=</code><code>new</code> <code>fileoutputstream(</code><code>new</code> <code>file(local));</code>
<code>157.</code><code>telnetinputstream ftpin = ftpclient.get(remote);</code>
<code>158.</code><code>byte</code><code>[] buff=</code><code>new</code> <code>byte</code><code>[</code><code>204800</code><code>];</code>
<code>159.</code><code>int</code> <code>len=</code><code>0</code><code>;</code>
<code>160.</code><code>while</code><code>((len=ftpin.read(buff))!=-</code><code>1</code><code>){</code>
<code>161.</code><code>out.write(buff,</code><code>0</code><code>,len);</code>
<code>162.</code><code>}</code>
<code>163.</code><code>out.close();</code>
<code>164.</code><code>ftpin.close();</code>
<code>165.</code><code>}</code>
<code>166.</code><code>public</code> <code>static</code> <code>void</code> <code>main(string args[])</code><code>throws</code> <code>exception{</code>
<code>167.</code><code>ftputils upfile=</code><code>new</code> <code>ftputils(</code><code>"192.168.187.130"</code><code>,</code><code>"root"</code><code>,</code><code>"1-1=0"</code><code>);</code>
<code>168.</code><code>upfile.login();</code>
<code>169.</code><code>list list=upfile.filenames(</code><code>"/"</code><code>);</code>
<code>170.</code><code>system.out.println(list);</code>
<code>171.</code><code>upfile.upfile(</code><code>"ftputils.java"</code><code>,</code><code>"/root/xjs/test/ftputils.java"</code> <code>);</code>
<code>172.</code><code>upfile.downfile(</code><code>"/root/xjs/2.txt"</code><code>,</code><code>"xjs/2.txt"</code> <code>);</code>
<code>173.</code><code>upfile.logout();</code>
<code>174.</code><code>}</code>
<code>175.</code><code>}</code>
<code>176.</code><code>/*</code>
<code>177.</code><code>以sun开头的class不是java里面的标准类,而是sun公司自己的的class,因此,他们位于rt.jar当中。因此,jdk源代码中没有提供源文件。但是,可以用诸如jad之类的反编译工具进行反编译。</code>
<code>178.</code><code>实际上,基本原理就是利用socket和serversocket来发送遵守ftp协议的消息,与ftp服务器进行交互。</code>
<code>179.</code><code>主要用到这么几个类:</code>
<code>180.</code><code>sun.net.ftp.ftpclient extends sun.net.transferprotocolclient</code>
<code>181.</code><code>sun.net.transferprotocolclient extends sun.net.networkclient</code>
<code>182.</code><code>sun.net.telnetinputstream extends filterinputstream</code>
<code>183.</code><code>sun.net.telnetoutputstream extends bufferedoutputstream</code>
<code>184.</code><code>因为是使用被动模式,因此,客户端要去连接服务端,</code>
<code>185.</code><code>在ftpclient的源代码的opendataconnection(string s)方法中有这么一句:</code>
<code>186.</code><code>serversocket = new serversocket(0, 1);也就是客户端随便选择一个空闲端口。</code>
<code>187.</code><code>也就是说,sun的ftpclient不支持主动模式。</code>
<code>188.</code><code>*/</code>