通常文件传输建议还是通过 ftp ,只有当 ftp 满足不了需求时,才考虑 hessian 的传输方案。
Hessian 传文件的应用场景有比如两台需要传输文件的服务器之间的网络情况限制比较严格,不允许 ftp 或新开端口之类;两台服务器之间传文件必须经过一台中间机器中转。还有就是获得比 ftp 传输更大的灵活性。上面的一些应用场景,都是在项目里实际遇到的。
Hessian 是不支持 File 的直接传输的,所以采取的方案是将 File 读到 byte[] 再用 hessian 传输。
不过最新的 hessian4.0 已经支持 InputStream 作为参数或返回值进行传输。
public String uploadStream(String filename, InputStream data)
{
HessianInerface hessianInerface = (HessianInerface) getHessianInterface();
return hessianInerface.uploadStream(filename, data);
}
但是以上2中方法都会有个问题,就是当文件比较大的时候,会报java.lang.OutOfMemoryError。
基于 byte[] 的方法的解决办法是将大的文件分成一小块一小块进行传输。
public String uploadSingleFiles(File file)
{
String logicPath = "" ;
InputStream is = null ;
try
{
byte [] buffer = null ;
HessianInerface hessianInerface = (HessianInerface) getHessianInterface();
is = new FileInputStream(file);
long size = file.length();
long perSize = onePerSize;
if (size > onePerSize)
{
long index = size / perSize;
if (size > perSize * index)
{
index = index + 1 ;
}
for ( long j = 1 ; j <= index; j ++ )
{
long curPerSize = perSize;
if (j == index)
{
curPerSize = size - perSize * (j - 1 );
}
buffer = new byte [( int ) curPerSize];
is.read(buffer);
if (j == 1 )
{
logicPath = hessianInerface.uploadSingleBigFile(buffer,
file.getName(), false );
} else
{
logicPath = hessianInerface.uploadSingleBigFile(buffer,
file.getName(), true );
}
}
} else
{
buffer = new byte [is.available()];
is.read(buffer);
logicPath = hessianInerface.uploadSingleFile(buffer, file
.getName());
}
} catch (IOException e)
{
throw new RuntimeException(e);
} finally
{
IOUtils.closeQuietly(is);
}
return logicPath;
}
基于 InputStream 的解决办法,最初想法讲 InputStream 分块读出传输,不过没成功,如果谁成功,请告诉我一声。
总结,如果 jvm 的内存设置比较大, InputStream 的方式是可以直接传输的,而 byte[] 的方式超过一定的大小就报错,在我的机器上大概 20M 左右。所以基于 byte[] 的分块传输是目前比较合理的解决办法。
代码比较多,我就不一一帖出了,在最后放出下载的链接,在服务端的实现类请根据自己的需求稍微修改下就能运行起来。
使用方法示例如下 :
HessianClient cl = new HessianClient();
cl.setHessianserviceurl( http://127.0.0.1:80/hessianService );
long onePerSize = 2080000 ;
cl.setOnePerSize(onePerSize);
File file1 = new File( " d:\\tddownload\\CJT.rar " );
cl.uploadSingleFiles(file1) ;
File ff = cl.downloadSingleBigFile( 23884L , " 中文9999.rar " ) ;
代码还可以继续完善的地方,比如加入文件的完整性校验,压缩传输等。
代码下载地址:http://www.blogjava.net/Files/magicdoom/hessianTransferFile.rar