【问题标题】:How to collect directory listing along with each file CRC checksum?如何收集目录列表以及每个文件的 CRC 校验和?
【发布时间】:2012-08-26 05:07:19
【问题描述】:

我使用以下命令在 nix(Linux、AIX、Sunos、HPUX) 平台中获取目录列表

命令

ls -latr 

输出

drwxr-xr-x  2 ricky support   4096 Aug 29 11:59 lib 
-rwxrwxrwx  1 ricky support    924 Aug 29 12:00 initservice.sh

cksum 命令用于获取 CRC 校验和。

如何在每个文件之后附加 CRC 校验和(包括目录列表),如下所示,在这些 nix(Linux、AIX、Sunos、HPUX)平台中保持以下格式?

drwxr-xr-x  2 ricky support   4096 Aug 29 11:59 lib 
-rwxrwxrwx  1 ricky support    924 Aug 29 12:00 initservice.sh 4287252281

更新说明:没有第三方应用程序,我使用 java/Groovy 将输出最终解析为使用 groovy XmlSlurper 形成 xml 的给定格式(生成的 XML 大小约为 5MB)

"permission","hardlink","owner","group","fsize","month","date","time","filename","checksum"

欢迎所有建议! :)

用我的代码更新

但我在这里计算 md5hex,它给出了与来自 linux 的 md5sum 命令类似的输出。所以它不再是cksum,因为我不能使用一些许可问题的jacksum bcz :(

class CheckSumCRC32 {

public def getFileListing(String file){
    def dir = new File(file)
    def filename = null
    def md5sum = null
    def filesize = null
    def lastmodified = null
    def lastmodifiedDate = null
    def lastmodifiedTime = null
    def permission = null
    Format formatter = null
    def list=[]
    if(dir.exists()){
        dir.eachFileRecurse (FileType.FILES) { fname ->
            list << fname
          }
        list.each{fileob->
            try{
                md5sum=getMD5CheckSum(fileob.toString())
                filesize=fileob.length()+"b"
                lastmodified=new Date(fileob.lastModified())
                lastmodifiedDate=lastmodified.format('dd/MM/yyyy')
                formatter=new SimpleDateFormat("hh:mm:ss a")
                lastmodifiedTime=formatter.format(lastmodified)
                permission=getReadPermissions(fileob)+getWritePermissions(fileob)+getExecutePermissions(fileob)
                filename=getRelativePath("E:\\\\temp\\\\recurssive\\\\",fileob.toString())
                println "$filename, $md5sum, $lastmodifiedDate, $filesize, $permission, $lastmodifiedDate, $lastmodifiedTime "
            }
            catch(IOException io){
                println io
            }
            catch(FileNotFoundException fne){
                println fne
            }   
            catch(Exception e){
                println e
            }           
        }
    }       
}

public def getReadPermissions(def file){
    String temp="-"
    if(file.canRead())temp="r"
    return temp
}
public def getWritePermissions(def file){
    String temp="-"
    if(file.canWrite())temp="w"
    return temp
}
public def getExecutePermissions(def file){
    String temp="-"
    if(file.canExecute())temp="x"
    return temp
}
public def getRelativePath(def main, def file){""
    return file.toString().replaceAll(main, "")
}


public static void main(String[] args) {
    CheckSumCRC32 crc = new CheckSumCRC32();
    crc.getFileListing("E:\\temp\\recurssive")
}
}

输出

release.zip, 25f995583144bebff729086ae6ec0eb2, 04/06/2012, 6301510b, rwx, 04/06/2012, 02:46:32 PM 
file\check\release-1.0.zip, 3cc0f2b13778129c0cc41fb2fdc7a85f, 18/07/2012, 11786307b, rwx, 18/07/2012, 04:13:47 PM 
file\Dedicated.mp3, 238f793f0b80e7eacf5fac31d23c65d4, 04/05/2010, 4650908b, rwx, 04/05/2010, 10:45:32 AM 

但我仍然需要一种方法来计算硬链接、所有者和组。我在网上搜索它看起来像java7 有这个能力&我被java6困住了。有什么帮助吗?

【问题讨论】:

  • 出于好奇:为什么不通过内置语言方式读取目录?毕竟你想要一个跨平台的应用,命令行工具的输出格式可能会有所不同!
  • 我会按照@Vlad 的建议尝试在 java 中执行此操作。您的所有权限、符号链接状态、大小等都应该可用docs.oracle.com/javase/tutorial/essential/io/fileAttr.html
  • @Vlad:最后,我希望输出采用所需的格式(请参阅 Qn),以便可以轻松地将其解析为特定列。我会多次查询这个问题,你会建议哪一个可以在不损失太多性能的情况下解决问题?
  • @Ricky:“不损失太多性能?”:“过早的优化是万恶之源”。先写代码,再优化,跟踪。瓶颈通常不在您期望的地方......
  • @Ricky:好吧,代码至少应该是正确的。只有当它正确时,我才会开始考虑性能。特别是对于您的情况,我怀疑启动另一个应用程序,让它以文本形式格式化结果并解析该结果比自己获取相同信息要快。

标签: java linux groovy solaris aix


【解决方案1】:

看看http://www.jonelo.de/java/jacksum/index.html - 据报道提供 cksum - 兼容 CRC32 校验和。

顺便说一句,我尝试使用 java.util.zip.CRC32 来计算校验和,它给出的值与 cksum 不同,因此必须使用稍微不同的算法。

编辑:我尝试了 jacksum,它可以工作,但你必须告诉它使用“cksum”算法 - 显然 与 jacksum 也支持的 crc32 不同。

【讨论】:

  • @GretBeardedGeek:我看到了您的链接,它是第 3 方实用程序,它甚至有我可以使用的 java 代码吗?还发现this 说jacksum 是开源的,所以它是作为一个库来的吗?
  • 从项目页面下载的内容包括jar文件和源代码。
【解决方案2】:

好吧,您可以运行该命令,然后对每一行运行 cksum 并将其附加到该行。

我做了以下事情:

dir = "/home/will"

"ls -latr $dir".execute().in.eachLine { line ->

  // let's omit the first line, which starts with "total"
  if (line =~ /^total/) return

  // for directories, we just print the line
  if (line =~ /^d/) 
  {
    println line
  } 
  else 
  {
    // for files, we split the line by one or more spaces and join 
    // the last pieces to form the filename (there must be a better 
    // way to do this)
    def fileName = line.split(/ {1,}/)[8..-1].join("")

    // now we get the first part of the cksum
    def cksum = "cksum $dir/$fileName".execute().in.text.split(/ {1,}/)[0]

    // concat the result to the original line and print it
    println "$line $cksum"
  }
}

特别注意我的“必须有更好的方法来做到这一点”。

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 2014-05-11
    • 2015-06-29
    • 2012-09-07
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多