Hola!
En esta ocasión y causante de una breve demostración que hice hace poco, estuve explicando un poco de inyección de métodos y de las ventajas que tienen sobre clases que comúnmente usamos en casos práctivos
En ese momento sugerí: ¿por qué no inyectamos un método a las clases java.io.File que permitan comprimir el archivo al cual están conteniendo?
Es un ejercicio simple para practicar la metaprogramación y las bondades del GDK en el manejo de archivos, y potencialmente es una forma en la cual se pueden agregar funcionalidades a clases propias o ajenas, elemento base para la creación de algunos plugins.
Aquí el ejemplo:
import java.util.zip.ZipOutputStream import java.util.zip.ZipEntry //Uso de metaClass para inyectar el método File.metaClass.zipMe = { -> // Obtenemos solo el nombre del archivo def onlyName = delegate.name.tokenize('.')[0] // Creamos nuestra clase que lo comprime ZipOutputStream zipFile = new ZipOutputStream(new FileOutputStream(onlyName+".zip")) // Creamos una entrada con el nombre del archivo zipFile.putNextEntry(new ZipEntry(delegate.name)) // Definimos un buffer def buffer = new byte[1024] // Operamos con el stream del archivo delegate.withInputStream { inputStream -> // Leemos y almacenamos en el buffer def sizeBytes = inputStream.read(buffer) // Escribimos en el archivo zip el buffer, desde cero y hasta el tamaño de bytes zipFile.write(buffer,0,sizeBytes) } // Terminamos la entrada del archivo zipFile.closeEntry() // Cerramos el archivo zip zipFile.close() } // Nombre del archivo String fileName = "README.txt" // Leemos el archivo def file = new File(fileName) // Comprimimos con el nombre del archivo file.zipMe()
Ahora bien, hacemos lo mismo de forma análoga pero con un directorio entero al cual estemos apuntando dentro del objeto File:
import java.util.zip.ZipOutputStream import java.util.zip.ZipEntry String inputDir = "graceworks" File.metaClass.zip = { -> def onlyName = delegate.name.tokenize('.')[0] def result = new ZipOutputStream(new FileOutputStream(onlyName+".zip")) result.withStream { zipOutStream-> delegate.eachFileRecurse { f -> if(!f.isDirectory()) { zipOutStream.putNextEntry(new ZipEntry(f.getPath())) new FileInputStream(f).withStream { inStream -> def buffer = new byte[1024] def count while((count = inStream.read(buffer, 0, 1024)) != -1) { zipOutStream.write(buffer) } } zipOutStream.closeEntry() } } } } def file = new File(inputDir) file.zip()
y estoy seguro, de que este código aún se puede mejorar o personalizar…
comments powered by Disqus