tomcat+apache+jk进行集群后,图片要进行共享,经过网上的搜索可以有多种方式实现。
一种是使用jcifs。jcifs可以实现网络中共享文件的读写,但是前提是,文件必须共享,还要在同一个局域网内。所以如果电脑上禁止了文件共享的话,就行不通了。
一种是使用sun提供的FtpClient。FtpClient从名字来看就知道了是通过FTP方式访问的。所以前提是服务器要有ftp服务。但是该类我不知道如何上传相同文件。看了网上的说明,上传要达到覆盖服务器上文件效果的话,要先使用sendServer()命令进行文件删除,而问题是我使用同样方法却无法删除文件。这种方法我也就放弃了。
还有一种就是apache提供的FTPClient(名字和sun的不同哦...)发现apache提供的比sun提供的好用,当然个人感觉而已。
public String writeFile(InputStream is,String fileName){ String newFileName = null;//上传到服务器上文件名称 //MyFTPClient类是我改写了FTPClient的类,其实也就改写了里面使用的端口 MyFTPClient ftp =null; try { ftp = new MyFTPClient(); ftp.connect(hostName,port);//建立连接 boolean b =ftp.login(userName, password);//登陆 if(!b) return "failed"; int reply = ftp.getReplyCode(); if(!FTPReply.isPositiveCompletion(reply)){ ftp.disconnect(); return "failed"; } /** * 设置上传类型,图片是二进制图片 * 默认使用的是ASCII编码的。因为图片是二进制文件。所以要设置一下 * 否则上传的图片就是大花脸了 */ boolean result=ftp.setFileType(ftp.BINARY_FILE_TYPE); ftp.changeWorkingDirectory("/"); /** * 上传文件 * fileName为上传到服务器的文件名 * * 这个方法我其实很纳闷,这个方法到底会不会覆盖服务器存在的文件我糊涂了, * 因为,第一次使用这个方法,我很清楚的记得,如果服务器上存在相同文件名, * 那么就不会上传这个文件,返回false。这也是我写下面while方法的原因, * 可是我写完后,再次运行,结果文件会覆盖,返回的一直是true,这让我很纳闷, * 如果谁知道原因请告诉我哦! * * 还有一个问题,就是这个方法可能会存在阻塞状态。跟踪源文件后,才发现这个方法里面 * 使用了socket,默认端口是0,如果服务器上设置了端口限制的话,就会因为端口没开导致阻塞状态。 * 这也是我改写FTPClient的原因了 。 * * FTPClient还有一个方法,就是storeUniqueFile方法,存储为唯一的文件名,即如果服务器存在这个文件 * 那么该文件会在文件名后面加1、2、3、4的。比如,我要上传1.jpg。但是是服务器上存在这个文件,那么 * 它会将1.jpg改成11.jpg,如果11.jpg还存在,就改为12.jpg,以此类推13.jpg... 直到服务器不存在为止。 * 但是使用这个有个问题,就是我不知道服务器最终存入的文件名是什么。 */ boolean bb =ftp.storeFile(fileName, is);//指定到服务器的文件名 /** * 因为一开始storeFile上传文件,如果服务器存在文件,就不会上传,返回false, * 所以写了一下几行,目的就是要获取最终上传到服务器的文件名 * 但是现在不知道什么原因,storeFile方法竟然会覆盖上传,所以下面写的也没什么意义了 */ int i=1; //如果上传失败,从新命名,再次上传,知道上传文件成功 while(!bb){ newFileName = i+fileName; bb=ftp.storeFile(newFileName, is); i++; } //为null表示第一次就上传成功了。 if(newFileName==null) newFileName = fileName; } catch (IOException e) { System.out.println("连接ftp失败!"); return "failed"; }finally{ try { if(is !=null) is.close(); if(ftp !=null || ftp.isConnected()) ftp.logout(); } catch (IOException e1) { } } System.out.println("上传文件成功!"); return newFileName ;//返回上传文件的文件名 }
一下是FTPClient中storeFile方法里使用socket的代码:
ServerSocket server; server = _serverSocketFactory_.createServerSocket(0, 1, getLocalAddress()); ...... try { //如果端口被限制了,这里就一直阻塞了 socket = server.accept(); } finally { server.close(); }
那个0就是端口,如果电脑的tcp端口设置了限制,那么可以自行设置端口了。