2009-12-15 24 views
5

假设我想获取由lstat()系统调用返回的文件的几个属性(所有者,大小,权限,次数)。在Java中执行此操作的一种方法是创建一个java.io.File对象,并对其执行诸如length(),lastModified()等调用。我有两个问题至今:用于Java的Unix stat()/ lstat()

  1. 这些调用中的每一个触发的stat()调用,并为我的目的STAT()s被认为昂贵的:我试图扫描数十亿个文件的并行上数百台主机和(到第一次近似)访问这些文件的唯一方法是通过NFS,通常针对加载了stat()的文件集群可能需要半秒钟的时间。调用不是lstat(),它通常是stat()(它遵循符号链接)或fstat64()(它打开文件并可能触发写操作来记录访问时间)。

有没有一种“正确”的方式来做到这一点,这样我最终只做一个lstat()调用并访问struct stat的成员?我从谷歌搜索迄今发现:

  • JDK 7将在java.nio.file的一切我想要的PosixFileAttributes接口(但如果我可以,我宁愿不进行夜间运行构建我的JDK躲开它)。

  • 我可以用JNI或JNA推出我自己的界面(但是如果存在现有界面,我宁愿不要)。

A previous similar question得到了几个建议的JNI/JNA实现。一个消失了,另一个维护得可疑(例如,没有下载,只是一个hg存储库)。

那里有更好的选择吗?

回答

2

看起来你几乎覆盖了所有的基地。当我开始阅读你的问题时,我首先想到的是JDK 7或JNI。在不了解这些文件的变化模式的任何信息的情况下,您可能还会考虑某种持久性缓存,例如嵌入式数据库。除NFS之外,您还可以查看其他一些访问方法,例如从远程主机提供批量文件信息的自定义Web服务。

+0

谢谢!最终我猜JDK 7并不是那么糟糕;我可以使用我正在编写的工具保留二进制文件,并且很快就会生成级别的软件。 – 2009-12-16 13:34:57

1

是的,stat()在所有调用和库下。这是一个延迟问题。但是,你可以同时执行多个stat(),因为有很多NFS服务器守护程序来支持你的连接,除非有人有一个异步stat(),否则使用线程。如果你可以通过ssh获得主机,stat()会便宜得多。你甚至可以编写一个tcp服务在路径中流式传输并传出stat()。不幸的是,访问NFS服务器是困难的或不可能的,因为它可能只有管理员帐户,成为Hitachi SAN或其他东西。

+0

有一点历史背景:有问题的NFS服务器是一个5-10PB的Isilon群集,它在stat调用时提供了严格的一致性,但是以争用时的可怕延迟为代价。 (我还不确定他们是否拥有一个大锁或更复杂的东西。)这是一个文件系统级别的问题:我们没有做任何更好的root操作。我们最终只是让它花费时间,而不是花几天的时间试图节省几天的计算机时间。 – 2016-12-30 03:53:00