Jump to content

How To Zip A Directory?


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

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 4 weeks later...

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 9 months later...

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

... 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
Link to comment
Share on other sites

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'

Link to comment
Share on other sites

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

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"
 

 )

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 2 years later...
  • Newbies

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 ?

Link to comment
Share on other sites

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. 

Link to comment
Share on other sites

  • Newbies

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
Link to comment
Share on other sites

This topic is 1895 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.