Groovy directory diff
A Java verziókban hanyagoltam a legalapabb megoldást: directory pollozó implementációt. Egyszerűen azért, mert Java nem egy barátságos nyelv és az IO API különösen nem az. (Miért? Mert nem szeretem a checked Exception-öket.).
Groovy/ viszont más. Abban lehet elegánsan is programozni. A következő példa nem is directory watch, csak egy példa implementáció arra, hogyan lehet beazonosítani a változásokat. A kulcsa a mapDiff
függvény.
NB: Ezt a scriptet használom a site feltöltésére, mert nem akarok mindent feltölteni, csak a változott tartalmakat.
1@GrabConfig(systemClassLoader=true) 2@Grapes([ 3@Grab(group='ant', module='ant', version='1.7.0'), 4@Grab(group='ant', module='ant-nodeps', version='1.6.5'), 5@Grab(group='ant', module='ant-apache-oro', version='1.6.5'), 6@Grab(group='ant', module='optional', version='1.5.4'), 7@Grab(group='commons-net', module='commons-net', version='1.4.1'), 8@Grab(group='commons-io', module='commons-io', version='2.4'), 9@Grab(group='ant', module='ant-jakarta-oro', version='1.6.1'), 10@Grab(group='ant', module='ant-commons-net', version='1.6.5') 11]) 12 13 14import org.apache.commons.net.ftp.FTPClient 15import org.apache.commons.io.* 16import groovy.io.FileType 17import java.security.MessageDigest 18import groovy.json.JsonBuilder 19import groovy.json.JsonSlurper 20 21ftp_host="xxx" 22ftp_user="xxx" 23ftp_pass="xxx" 24ftp_dir='xxx' 25 26scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent 27checksumFile = new File(scriptDir, "../tmp/gchecksum.json") 28base_dir = new File(scriptDir, "../output") 29println base_dir 30 31def main(){ 32 def currentHash = generateHash() 33 if(!checksumFile.exists()){ 34 upload(currentHash, [:]) 35 writeChecksum(currentHash) 36 return 37 } 38 println 'Comparing...' 39 println 'Reading previous hash...' 40 def preHash = readHash() 41 def diff = mapDiff(preHash, currentHash) 42 println 'Removed' 43 println diff.removed 44 println 'Changed' 45 def changed = [:] 46 changed.putAll(diff.added) 47 changed.putAll(diff.changed) 48 println changed 49 upload(changed, diff.removed) 50 writeChecksum(currentHash) 51} 52 53def generateHash(){ 54 println 'Generating current hash...' 55 Map hashes = [:] 56 allFiles(base_dir).each{ File file -> 57 def md = generateMD5(file) 58 hashes[file.path.substring(base_dir.path.length()+1)]=md 59 } 60 println "${hashes.size()} hashes are generate." 61 hashes 62} 63 64def allFiles(File dir){ 65 def list = [] 66 dir.eachFileRecurse (FileType.FILES) { file -> 67 list << file 68 } 69 list 70} 71 72def generateMD5(final file) { 73 MessageDigest digest = MessageDigest.getInstance("MD5") 74 file.withInputStream(){is-> 75 byte[] buffer = new byte[8192] 76 int read = 0 77 while( (read = is.read(buffer)) > 0) { 78 digest.update(buffer, 0, read); 79 } 80 } 81 byte[] md5sum = digest.digest() 82 BigInteger bigInt = new BigInteger(1, md5sum) 83 return bigInt.toString(16).padLeft(32, '0') 84} 85 86def toJson(m){ 87 builder = new JsonBuilder() 88 builder(m) 89 builder.toString() 90} 91 92def writeChecksum(m){ 93 checksumFile.text=toJson(m) 94} 95 96def readHash(){ 97 slurper = new JsonSlurper() 98 slurper.parseText(checksumFile.text) 99} 100 101def mapDiff(Map oldMap, Map newMap){ 102 def newKeys = newMap*.key 103 def oldKeys = oldMap*.key 104 105 def removedKeys = oldKeys-newKeys 106 def addedKeys = newKeys - oldKeys 107 def commonKeys =newKeys - removedKeys - addedKeys 108 def changedKeys = commonKeys.findAll { oldMap[it] != newMap[it] } 109 def unchangedKeys = commonKeys - changedKeys 110 111 def changes = [ 112 removed: oldMap.findAll { it.key in removedKeys }, 113 added: newMap.findAll { it.key in addedKeys }, 114 changed: oldMap.findAll { it.key in changedKeys }, 115 unchanged: newMap.findAll { it.key in unchangedKeys } 116 ] 117} 118 119 120def upload(uploadable, deletable){ 121 def ant = new AntBuilder() 122 if(uploadable.size() != 0){ 123 ant.ftp(server: ftp_host, 124 userid: ftp_user, 125 password: ftp_pass, 126 remotedir: ftp_dir, 127 passive:"yes", 128 verbose: "yes", 129 binary:"yes", 130 action: "put"){ 131 fileset(dir:base_dir.path){ 132 uploadable.each{ 133 include(name:it.key) 134 } 135 } 136 } 137 } 138 if(deletable.size() == 0){ 139 return 140 } 141 ant.ftp(server: ftp_host, 142 userid: ftp_user, 143 password: ftp_pass, 144 remotedir: ftp_dir, 145 passive:"yes", 146 verbose: "yes", 147 binary:"yes", 148 action: "delete"){ 149 fileset(dir:base_dir.path){ 150 deletable.each{ 151 include(name:it.key) 152 } 153 } 154 } 155} 156 157main()
Directory Watcher
- Mi az a Directory Watcher?
- Java directory watcher
- JNotify
- JPathwatch
- Java 7 NIO notification
- Pollozó megoldás
- Groovy directory diff
- Groovy pollozó megoldás
Sep 22, 2013
comments powered by Disqus