swl Posted December 22, 2010 Posted December 22, 2010 Hi all, I'm a "noob" at ScriptMaster and have seen how to zip a selected file with the example code. Does anyone have a good example of how to zip an entire directory/folder? TIA, Denis
Smef Posted December 22, 2010 Posted December 22, 2010 The current module does not have the ability to zip a directory. If you are interested in having us make you a module to do this please send an email to [email protected].
john renfrew Posted December 24, 2010 Posted December 24, 2010 Or use this // ZipDir ( fm_dirIn ; fm_fileOut ) // 10_12_23_JR WORKING // v1.0 // adds all of tree from starting directory to zip file // adapted from Solomon Duskis, http://www.jroller.com import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream try { topDir = new File(fm_dirIn) zipOut = new ZipOutputStream ( new FileOutputStream(fm_fileOut) ); topDirLength = topDir.absolutePath.length() topDir.eachFileRecurse{ file -> relPath = file.absolutePath.substring(topDirLength).replace('\\', '/') if ( file.isDirectory() && !relPath.endsWith('/')){ relPath += "/" } entry = new ZipEntry(relPath) entry.time = file.lastModified() zipOut.putNextEntry(entry) if( file.isFile() ){ zipOut << new FileInputStream(file) } } zipOut.close() } catch (Exception e) { e.printStackTrace() } return true 1
john renfrew Posted December 25, 2010 Posted December 25, 2010 And if you want a full recursive unzip try this // unZipDir ( fm_dirOut ; fm_fileIn ) // 10_12_23_JR WORKING // v1.1 // unzips nested files from zip file // adapted from jsshah, http://www.stackoverflow.com import java.io.FileInputStream import java.io.FileOutputStream import java.util.zip.ZipInputStream try { int BUFFER_SIZE = 2048 fis = new FileInputStream(new File(fm_fileIn)) zis = new ZipInputStream(new BufferedInputStream(fis)) while((entry = zis.getNextEntry()) != null) { outFile = fm_dirOut + entry.getName() name = entry.getName() if (name.endsWith("/")) { newDirs = new File(fm_dirOut + name) if(!newDirs.mkdirs() && !newDirs.isDirectory()) { // dir creation failed return ERROR } //newDirs.mkdirs() } else { byte[] data = new byte[bUFFER_SIZE]; fos = new FileOutputStream(outFile) dest = new BufferedOutputStream(fos, BUFFER_SIZE) while((count = zis.read(data, 0, BUFFER_SIZE)) != -1) { dest.write(data, 0, count) } //end while //close the output streams dest.flush() dest.close() } //end while } //finished with all the files, so close the zip zis.close() } catch(Exception e) { e.printStackTrace() return false } return true 2
swl Posted December 28, 2010 Author Posted December 28, 2010 John, This works beautifully for exactly what I was looking for. Thanks very much for the help!!! Kind regards, Denis Or use this // ZipDir ( fm_dirIn ; fm_fileOut ) // 10_12_23_JR WORKING // v1.0 // adds all of tree from starting directory to zip file // adapted from Solomon Duskis, http://www.jroller.com import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream try { topDir = new File(fm_dirIn) zipOut = new ZipOutputStream ( new FileOutputStream(fm_fileOut) ); topDirLength = topDir.absolutePath.length() topDir.eachFileRecurse{ file -> relPath = file.absolutePath.substring(topDirLength).replace('\\', '/') if ( file.isDirectory() && !relPath.endsWith('/')){ relPath += "/" } entry = new ZipEntry(relPath) entry.time = file.lastModified() zipOut.putNextEntry(entry) if( file.isFile() ){ zipOut << new FileInputStream(file) } } zipOut.close() } catch (Exception e) { e.printStackTrace() } return true
laudmusic Posted January 23, 2011 Posted January 23, 2011 This works awesome!!!!! Can you shed some light on how I might amend the code so I can just add a list of files to the zip instead of copying them to a directory first? My goal is to grab a bunch of files, get their locations, then create a zip and add each file to it. I guess it would be an amend, but I really thought/remember that via command line there was a way to list files to add. Any light that could be shed would be awesome. Thanks! Or use this // ZipDir ( fm_dirIn ; fm_fileOut ) // 10_12_23_JR WORKING // v1.0 // adds all of tree from starting directory to zip file // adapted from Solomon Duskis, http://www.jroller.com import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream try { topDir = new File(fm_dirIn) zipOut = new ZipOutputStream ( new FileOutputStream(fm_fileOut) ); topDirLength = topDir.absolutePath.length() topDir.eachFileRecurse{ file -> relPath = file.absolutePath.substring(topDirLength).replace('\\', '/') if ( file.isDirectory() && !relPath.endsWith('/')){ relPath += "/" } entry = new ZipEntry(relPath) entry.time = file.lastModified() zipOut.putNextEntry(entry) if( file.isFile() ){ zipOut << new FileInputStream(file) } } zipOut.close() } catch (Exception e) { e.printStackTrace() } return true
Fenton Posted January 23, 2011 Posted January 23, 2011 The zip works. But it always returns 1, even if it doesn't. Could it be rewriten slightly to show an error in either input or output path? Also, small likely unavoidable glitch with Mac ".text clipping" files (with or without extension). The content is lost, even if plain text. I say unavoidable because native Mac command line 'zip' does this also; 'ditto' keeps that resource fork, maybe others.
Noél Dubau Posted November 10, 2011 Posted November 10, 2011 Hello, I need to create a zip of a folder ; I was glad to find that SM script but if it seems to work (I find the output file with a good capacity) I can't open it under Winzip, either on a PC or a Mac ; I get an error I've translated Extraction towards C:UsersAdministrateurAppDataLocalT emp Use Road: not files Overlay: yes attention: name of not corresponding file: Factures_PDFLOCAL201110_octobreDub au_No + ½ l_Dubau_Louise.pdf error: no files found - nothing to make I tried to extract one after one the files ; the error occurs when the file contains an accentuated char : so No + ½ l ir really Noël Is it possible to correct the script ? Thanks for your help Noël
john renfrew Posted November 11, 2011 Posted November 11, 2011 Noel... This is relevant - it is a function of using the base Java zip library. >> Java currently expects UTF-8 encoding. This generally means that if you create a ZIP file in Windows, filenames with non-ASCII characters will be mangled. The issue has been raised as Java bug ID 4244499, with a proposal to add a ZipFile constructor to take the character encoding (assuming the caller knows it). At the moment, a possible solution is to use the Arcmexer library, which allows you to set the file name encoding. This also has the advantage of being able to read encrypted ZIP files. My advice is generally: Don't use accents or other non-ASCII characters or spaces in filenames! You really don't need them that much. One historical problem is that filenames were never really intended to be a human-readable "title", but increasingly, that's how many "average users" are treating them. For the time being, there's no elegant solution to this problem, and the best we can really do is live with filenames with missing diacritics or occasional spelling changes to fit ASCII.
john renfrew Posted November 11, 2011 Posted November 11, 2011 Fenton Sorry I seem to have missed this How about // ZipDir ( fm_dirIn ; fm_fileOut ) // 10_12_23_JR WORKING // v1.1 // adds all of tree from starting directory to zip file // adapted from Solomon Duskis, http://www.jroller.com import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream try { topDir = new File(fm_dirIn) zipOut = new ZipOutputStream ( new FileOutputStream(fm_fileOut) ) topDirLength = topDir.absolutePath.length() topDir.eachFileRecurse{ file -> relPath = file.absolutePath.substring(topDirLength).replace('', '/') if ( file.isDirectory() && !relPath.endsWith('/')){ relPath += '/' } entry = new ZipEntry(relPath) entry.time = file.lastModified() zipOut.putNextEntry(entry) if( file.isFile() ){ zipOut << new FileInputStream(file) } } zipOut.close() } catch (Exception e) { return 'ERROR ' + e.getMessage() //e.printStackTrace() } if (!new File(fm_fileOut).exists()){return 'ERROR'} return true
Noél Dubau Posted November 11, 2011 Posted November 11, 2011 Thanks for these answers ! I know that all these chars are sources of problems ; but for a basic user it's easier to understand what contains a file called "Dubau Noël bill.pdf" than called "X354_2011_bill.pdf" ! The solution was given in private to use a SM script which remove all diacrticals chars before zipping. You can find it at http://www.fmsource.com/index.php/topic/46544-formatage-de-caracteres-accentues-a-transformer-en-caracteres-sans-accent/page__p__222476__hl__removediacriticals__fromsearch__1#entry222476 Noël (alias Christmas )
john renfrew Posted November 12, 2011 Posted November 12, 2011 There is a solution that might work using Ant. You need the ant.jar and ant-launcher.jar files IN THE CLASSPATH (java/extensions) but I have successfully zipped and unzipped files with diacriticals in the names using this method - seems to work with the French marks but not Żywia - must be an encoding issue there.. Thanks to Clement Hoffman for the steer basic code - needs lots of bits round it: def fm_dirSource = "/Users/RWU/Downloads/TEMP" def fm_fileDest = "/Users/RWU/Desktop/test.zip" if (new File(fm_dirSource).exists() && fm_fileDest){ def ant = new AntBuilder() ant.zip(basedir:fm_dirSource, destfile:fm_fileDest) //ant.zip(basedir:fm_dirSource, destfile:fm_fileDest, update:"true") return true } else return "ERROR" see the docs for more details http://ant.apache.or.../Tasks/zip.html
clemhoff Posted November 12, 2011 Posted November 12, 2011 ... a more extended version of my original script : // USAGE : ZipAnt ( fm_dirSource ; fm_archOut ; fm_archUpdate ; fm_archCompLevel ; fm_archExclude ) // 2011_11_11 clem & John Renfrew // v1.0 // example: // ZipAnt ( pathToDir ; pathToZip ; true/false ; 0..9 ; *.html, *.csv, *.xlsx ) if ( new File(fm_dirSource).exists() && fm_archOut ){ def ant = new AntBuilder() fm_archUpdate = fm_archUpdate ?: true fm_archCompLevel = fm_archCompLevel ?: 9 ant.zip( basedir: fm_dirSource, destfile: fm_archOut, update: fm_archUpdate, level: fm_archCompLevel, excludes: fm_archExclude ) } else return "ERROR" ... diacriticals are apparently preserved ... 1
john renfrew Posted November 12, 2011 Posted November 12, 2011 Clem better error reporting // ZipAnt ( fm_dirSource ; fm_archOut ; fm_archUpdate ; fm_archCompLevel ; fm_archExclude ) // 2011_11_11 clem & John Renfrew // v1.1 // example: // ZipAnt ( pathToDir ; pathToZip ; true/false ; 0..9 ; *.html, *.csv, *.xlsx ) if ( new File(fm_dirSource).exists() && fm_archOut ){ ant = new AntBuilder() fm_archUpdate = fm_archUpdate ?: true fm_archCompLevel = fm_archCompLevel ?: 9 try{ ant.zip( basedir: fm_dirSource, destfile: fm_archOut, update: fm_archUpdate, level: fm_archCompLevel, excludes: fm_archExclude ) } catch (e) { return e.getMessage() } // or replace with with success message of your choice return true } else return 'ERROR'
Noél Dubau Posted November 13, 2011 Posted November 13, 2011 ... Thanks for your following of the question, and especially to the "newbie" Clem Noël
Newbies Orsini Posted November 14, 2014 Newbies Posted November 14, 2014 Thank you for this helpful function, Jhon. Raphaël.
jsubiros Posted February 13, 2016 Posted February 13, 2016 Can anybody explain me how can we register this function into filemaker with scriptmaster plugin ?? I did like this but it doesn't run: RegisterGroovy( "ZipDir( fm_dirIn ; fm_fileOut )" ; "import java.io.File¶ ¶ import java.io.FileInputStream¶ ¶ import java.io.FileOutputStream¶ ¶ import java.util.zip.ZipEntry¶ ¶ import java.util.zip.ZipOutputStream¶ ¶ try {¶ ¶ topDir = new File(fm_dirIn)¶ ¶ zipOut = new ZipOutputStream ( new FileOutputStream(fm_fileOut) );¶ ¶ topDirLength = topDir.absolutePath.length()¶ ¶ topDir.eachFileRecurse{ file ->¶ ¶ relPath = file.absolutePath.substring(topDirLength).replace('\', '/')¶ ¶ if ( file.isDirectory() && !relPath.endsWith('/')){¶ ¶ relPath += "/"¶ ¶ }¶ ¶ entry = new ZipEntry(relPath)¶ ¶ entry.time = file.lastModified()¶ ¶ zipOut.putNextEntry(entry)¶ ¶ if( file.isFile() ){¶ ¶ zipOut << new FileInputStream(file)¶ ¶ }¶ ¶ }¶ ¶ zipOut.close()¶ ¶ } catch (Exception e) {¶ ¶ e.printStackTrace()¶ ¶ }¶ ¶ return true" )
john renfrew Posted February 14, 2016 Posted February 14, 2016 One way: you need to set a variable to this code then check that the variable you set is 1 and not an error then the function should appear in your list of external functions
jsubiros Posted February 14, 2016 Posted February 14, 2016 (edited) I am obtaining a disaster zip with a lot of directories and nosense. If i put this code: relPath = file.absolutePath.substring(topDirLength).replace('\\', '/') There is an error in the java. And if I put with only one '\' i get a bad zip.... Can anybody helps me ? Thanks. Edited February 16, 2016 by jsubiros
Newbies FileMakerNewbee Posted February 8, 2019 Newbies Posted February 8, 2019 Hello There, I am trying to use John's script v1.1 with ScriptMaster plugin but without success. I have a little experience with this plugin and for instance, i am able to register and evaluate the script provided by 360Works "Zip File( src ; destination )" without any issue. But my actual need is to zip a folder and i was very happy to find this post. Unfortunately, i am unable to Register John's script (evaluating into a variable it returns just "ERROR" instead of 1) and i am also unable to evaluate/perform it; i always get this message : java.lang.reflect.InvocationTargetException Are there specific requirements to register/evaluate John's script with ScriptMaster ?
ryan360Works Posted February 8, 2019 Posted February 8, 2019 Hello, Are you using the latest version of ScriptMaster, 5.1?
Newbies FileMakerNewbee Posted February 8, 2019 Newbies Posted February 8, 2019 (edited) Hi Ryan, Thank you for helping ! Yes my ScriptMaster version is 5.1. Sounds like there are no update since june 2018. Edited February 8, 2019 by FileMakerNewbee
ryan360Works Posted February 8, 2019 Posted February 8, 2019 I have seen the InvocationTargetException happen at different points. Please send an email to [email protected] with your plugin logs. This will create an official support ticket for you. See this page for log locations. Make sure to reproduce the error and then send the logs before any restarts of FileMaker as restarting will overwrite the logs.
john renfrew Posted February 9, 2019 Posted February 9, 2019 Let me look at whether I have amended that code at all too... it IS now over 8 years old!! 1
Newbies FileMakerNewbee Posted February 11, 2019 Newbies Posted February 11, 2019 John, it is very kind from you. I understand the thread is very old. What i can tell is that i have not found many other solution like yours.
Newbies FileMakerNewbee Posted February 15, 2019 Newbies Posted February 15, 2019 (edited) Hello there ! For potential futur visitor, i have to say i found out a free and simple way by using BaseElement "Zip" and "FileListFolder" functions : https://baseelementsplugin.zendesk.com/hc/en-us/articles/206609058-BE-Zip https://baseelementsplugin.zendesk.com/hc/en-us/articles/204700868-BE-FileListFolder It works like a charm and appear to be more straight forward than using a groovy and ScriptMaster. Just had the surprise on windows that a path had to begin with C:/… instead of usual /C:/… whereas on macOS, the path can start as usual by /Volumes/Hard Disk/… Here is an FileMaker script sample that worked for me : Set Variable [ $path; Value:Substitute ( <FileMakerPathOfAFolder> ;"file:/" ; If ( Get ( SystemPlatform ) = 1 ; "/Volumes/" ; "" ))] Set Variable [ $files_names; Value:BE_FileListFolder ( $path ) ] Loop Set Variable [ $i; Value: $i + 1 ] Set Variable [ $files_path; Value:List( $files_path ; $path & GetValue ( $files_names ; $i ) ) ] End of Loop if [ $i = CountValues ( $files_names ) ] End of Loop Set Variable [ $Zip; Value:BE_Zip ( $files_path ) ] . Edited February 15, 2019 by FileMakerNewbee
Recommended Posts
This topic is 2119 days old. Please don't post here. Open a new topic instead.
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now