ZipFiles

Igor Pro 9 will include an UnzipFile operation.

Here is a barebones utility for the reverse process, creating an archive. I haven't tested it much, especially on Windows. This overwrites existing archives.

function zipGUI()
	// get a list of files to zip
	variable refnum
	string fileFilters = "All Files:.*;"
	Open /D/R/F=fileFilters/MULT=1/M="Select files to zip" refnum
	if (strlen(S_fileName) == 0)
		return 0
	endif
	zipFiles(ReplaceString("\r", S_fileName, ";"), "")
end

// utility function, creates a zip archive
// all paths are junked, no subfolders are preserved.
// not tested much on windows
function zipFiles(string FilePathListStr, string zipPathStr)
	int verbose = 1 // choose whether to print output from executescripttext
	string msg = "", cmd = "", zipFileStr = ""
	int i, numfiles
	
	numfiles = ItemsInList(FilePathListStr)
	for (i=0;i<numfiles;i+=1)
		GetFileFolderInfo /Q/Z StringFromList(i, FilePathListStr)	
		if (V_Flag || V_isFile==0)
			printf "Could not find %s\r", StringFromList(i, FilePathListStr)
			return 0
		endif
	endfor
	
	if (strlen(zipPathStr) == 0)
		zipPathStr = SpecialDirPath("Desktop",0,0,0)
		zipFileStr = "archive.zip"
		DoAlert 1, "Zip to Desktop:archive.zip?"
		if (v_flag == 2)
			return 0
		endif
	else
		if (cmpstr(zipFileStr[strlen(zipFileStr)-1], ":") == 0)
			zipFileStr = "archive.zip"
		else
			zipFileStr = ParseFilePath(0, zipPathStr, ":", 1, 0)
			zipPathStr = ParseFilePath(1, zipPathStr, ":", 1, 0)
		endif		
		GetFileFolderInfo /Q/Z zipPathStr
		if (V_Flag || V_isFolder==0)
			sprintf msg, "Could not find zipPathStr folder\rCreate %s?", zipPathStr
			DoAlert 1, msg
			if (v_flag == 2)
				return 0
			endif
		endif
	endif
	
	// make sure zipPathStr folder exists - necessary for mac
	NewPath /C/O/Q acw_tmpPath, zipPathStr
	KillPath /Z acw_tmpPath

	if (stringmatch(StringByKey("OS", IgorInfo(3))[0,2],"Win")) // Windows
		string strVersion = StringByKey("OSVERSION", IgorInfo(3))
		variable WinVersion = str2num(strVersion) // turns "10.1.2.3" into 10.1 and 6.23.111 into 6.2 (windows 8.0)
		if (WinVersion<6.3)
			Print "zipArchive requires Windows 10 or later"
			return 0
		endif
		
		zipPathStr = ParseFilePath(5, zipPathStr, "\\", 0, 0)
		cmd = "powershell.exe Compress-Archive -Force -LiteralPath "
		string strPath
		for (i=0;i<numFiles;i+=1)
			strPath = ParseFilePath(5, StringFromList(i, FilePathListStr), "\\", 0, 0)
			strPath = replacestring("'", strPath, "''")
			cmd += SelectString(i>0, "", ", ") + "'" + strPath + "'"
		endfor
		
		strPath = replacestring("'", zipPathStr + zipFileStr, "''")
		cmd += " -DestinationPath '" + strPath + "'"
	else // Mac
		zipPathStr = ParseFilePath(5, zipPathStr, "/", 0, 0)
		
		sprintf cmd, "zip -j -r -X \\\"%s%s\\\"", zipPathStr, zipFileStr
		
		for (i=0;i<numfiles;i++)
			cmd += " \\\"" + ParseFilePath(5, StringFromList(i, FilePathListStr), "/", 0,0) + "\\\""
		endfor
		sprintf cmd, "do shell script \"%s\"", cmd
	endif
	
	ExecuteScriptText /B/UNQ/Z cmd
	if (verbose)
		Print S_value // output from executescripttext
	endif
	
	return (v_flag == 0)
end

 

Awesome! This gives me an Idea to write something for loading zipped data. Some data files I use even have a compression ratio > 100! I wonder if there is a smart way to unzip a file directly into Igor's memory. I guess the approach would be to unzip into a temporary file, load the file and then delete the temporary file. It's a bit scary to wrangle with files on disk that way.

Both my hack for Igor 8 and Igor 9's UnzipFile work only with file input, so you'd have to add the temporary file step. There's an XOP that's supposed to work with strings.

You could take a look at the way I deal with unzipping to a temporary file in the Updater project.

Yeah, I will take a look. I want to release some projects of mine soon, so I wanted to get to the updater anyway to make things compatible.

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More