设为首页 收藏本站
查看: 537|回复: 0

[经验分享] Java 利用Linux Openssl 库计算文件校验码

[复制链接]

尚未签到

发表于 2016-3-17 09:23:39 | 显示全部楼层 |阅读模式
在传统Java编程中, 我们可以另用ProcessBuilder类来创建系统进程或者Runtime类来取得JVM的接口对象运行我们指定的系统命令, 并且可以通过读入器来获取系统的out以及err输出.这里有一个简单的例子, 没有用过的同学可以参考一下.
http://wuhongyu.iyunv.com/blog/461477
由于前段时间有这样的一个需求, 尽可能快的算出Hadoop系统里的MD码, 我曾经想过另用Java的Digest类来读取文件, 然后工作交给Digest类来完成, 可没想到的是Java的这个类算MD校验码,效率及其的低下,我在XP上算50M的文件, 居然花费8秒钟的时间.直接放弃. 这个Demo我也顺便推荐一下:
http://www.javablogging.com/?s=Java+Digest+SHA1+MD5
后来google该问题的解决方案, 有一个比较有意思的贴子Fast MD5 Implementation in Java, 呵呵, 由于时间关系, 没来的急看,分享一下:
http://www.twmacinta.com/myjava/fast_md5.php
Fast MD5.. 总给我一个不太舒服的感觉, 最后还是决定放弃使用. 由于Hadoop运行于Linux 环境, 回过神来我想到了Linux上的openssl库. 大伙都知道openssl 里其中就有计算数据的安全通信命令. $cat XXX | openssl sha1.
这里有一个问题, 由于hadoop的文件是存在于集群的, 而openssl 是接受本地文件作为参数的, 我可以把文件从HDFS里读出, 然后再构造文件供openssl 计算. 不过这种方式太囧.
我的解决方法是另用Runtime获取运行对象, 直接执行openssl sha1命令, 其实当系统执行该命令的时候会等待输入的. 此时我可以通过我的文件输入流把数据打印到等待输入的输出流上。
// TODO this is a job. not a filedescriptor
protected void handle(FileDescriptor job) throws IOException {
if (job == null || job.path == null) {
log.warn("Invalid job: " + job);
}
// wait for GC.
Configuration conf = new Configuration();
Path path = new Path(job.path);
FileSystem fs = path.getFileSystem(conf);
if (!fs.exists(path) || !fs.isFile(path)) {
log.warn("*HADLEJOB file does not exist for path: " + path);
return;
}
InputStream is = fs.open(path);
// Run a command
String cmd = "openssl sha1";
boolean completed = false;
Process process = null; // Sub process used to execute the command
int exitCode;
process = Runtime.getRuntime().exec(cmd);
BufferedOutputStream os = new BufferedOutputStream(process.getOutputStream(), 4096);
byte buf[] = new byte[4096];
while (true) {
int bytesRead = is.read(buf);
if (bytesRead == -1) {
break;
}
os.write(buf, 0, bytesRead);
}
os.flush();
os.close();
final BufferedReader errReader =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
BufferedReader inReader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
final StringBuffer errMsg = new StringBuffer();
// read error and input streams as this would free up the buffers
// free the error stream buffer
Thread errThread = new Thread(){
public void run() {
try {
String line = errReader.readLine();
while ((line != null) && !isInterrupted()) {
errMsg.append(line);
errMsg.append(System.getProperty("line.separator"));
line = errReader.readLine();
}
} catch (IOException ioe) {
log.warn("Error reading the error stream", ioe);
}
}
};
try {
errThread.start();
} catch (IllegalStateException ise) {
}
try {
String line = inReader.readLine();
if (line == null) {
throw new IOException("Exception a line not the end of stream");
}
job.set_sha1(line.trim());
// clear the input stream buffer
line = inReader.readLine();
while (line != null) {
line = inReader.readLine();
}
// wait for the process to finish and check the exit code
exitCode = process.waitFor();
try {
errThread.join();
} catch (InterruptedException ie) {
log.warn("Interrupted while reading the error stream", ie);
}
completed = true;
if (exitCode != 0) {
throw new IOException(exitCode + errMsg.toString());
}
} catch (InterruptedException ie) {
throw new IOException(ie.toString());
} finally {
// close the input stream
try {
inReader.close();
} catch (IOException e) {
log.warn("Error whilke closing the input stream", e);
}
if (!completed) {
errThread.interrupt();
}
try {
errReader.close();
}catch(IOException ioe){
log.warn("Error while closing the error stream", ioe);
}
process.destroy();
}
}

该执行方法运行于线程池中, 下一个贴子我将记录真正应用中线程池的实现, 提供线程池的大小设置, shrink等实现.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-191899-1-1.html 上篇帖子: nohup命令让程序在后台运行-linux 下篇帖子: 【转】JAVA字符集,linux下中文问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表