Jump to content
Claris Engage 2025 - March 25-26 Austin Texas ×

This topic is 2119 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Posted

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

Posted

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

  • Like 1
Posted

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



  • Like 2
Posted

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

  • 4 weeks later...
Posted

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

Posted

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.

  • 9 months later...
Posted

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

Posted

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.

Posted

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

Posted

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 :yep: )

Posted

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

Posted

... 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 ...

  • Like 1
Posted

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'

  • 3 years later...
  • 1 year later...
Posted

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"
 

 )

 

Posted

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

 

 

Posted (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 by jsubiros
  • 2 years later...
  • Newbies
Posted

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 ?

Posted

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. 

Posted

Let me look at whether I have amended that code at all too... it IS now over 8 years old!!

  • Like 1
  • Newbies
Posted (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 by FileMakerNewbee

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.