block-level on error undo, throw.
using System.IO.Compression.CompressionLevel from assembly.
using System.IO.Compression.ZipArchive from assembly.
using System.IO.Compression.ZipArchiveEntry from assembly.
using System.IO.Compression.ZipArchiveMode from assembly.
using System.IO.FileAccess from assembly.
using System.IO.FileMode from assembly.
using System.IO.FileShare from assembly.
using System.IO.FileStream from assembly.
using System.IO.Path from assembly.
using System.IO.Stream from assembly.
define temp-table ttSourceFile
field fullpathname as character
field filename as character.
/* ******************** Preprocessor Definitions ******************** */
/* ************************ Function Prototypes ********************** */
function IsFileLocked returns logical private
(input filename as character) forward.
/* *************************** Main Block *************************** */
define variable sourceFolderPath as character no-undo.
define variable zipFile as character no-undo.
define variable filename as character no-undo.
define variable files as class "System.String[]" no-undo.
assign
sourceFolderPath = session:temp-directory
zipFile = sourceFolderPath + substitute('\&1.zip', iso-date(today)) .
files = System.IO.Directory:GetFiles(sourceFolderPath).
define variable indexpos as integer no-undo.
do indexpos = 1 to files:length:
filename = files:GetValue(indexpos - 1).
//Exclude all zip files.
if filename matches "*.zip" then
next.
file-info:file-name = filename.
if file-info:file-create-date lt today then
do:
if IsFileLocked(input file-info:full-pathname) then
next.
create ttSourceFile.
assign
ttSourceFile.filename = Path:GetFileName(file-info:full-pathname) //
ttSourceFile.fullpathname = file-info:full-pathname.
end.
end.
run CreateZIPFile(input zipFile).
file-info:file-name = zipFile.
message file-info:full-pathname
view-as alert-box info.
return.
finally:
empty temp-table ttSourceFile.
end finally.
/* ********************** Internal Procedures *********************** */
procedure CreateZIPFile private:
/*------------------------------------------------------------------------------
Purpose:
Notes:
------------------------------------------------------------------------------*/
define variable fileEntry as class ZipArchiveEntry no-undo.
define variable fileEntryStream as class Stream no-undo.
define variable sourceFileStream as class FileStream no-undo.
define variable zipFileStream as class FileStream no-undo.
define variable archive as class ZipArchive no-undo.
define input parameter zipFile as character no-undo.
zipFileStream = new FileStream(zipFile, FileMode:Create).
archive = new ZipArchive(zipFileStream, ZipArchiveMode:Create).
for each ttSourceFile:
fileEntry = archive:CreateEntry(ttSourceFile.filename, CompressionLevel:Fastest).
fileEntryStream = fileEntry:Open().
sourceFileStream = System.IO.File:OpenRead(ttSourceFile.fullpathname).
if sourceFileStream:CanRead then
do:
sourceFileStream:CopyTo(fileEntryStream).
sourceFileStream:Close().
end.
//Closes the current stream and releases any resources associated with the current stream.
fileEntryStream:Close().
end.
catch e1 as Progress.Lang.Error :
message e1:GetMessage(1)
view-as alert-box error.
end catch.
finally:
//Clears buffers for this stream and causes any buffered data to be written to the file.
zipFileStream:Flush().
// This method finishes writing the archive and releases all resources used by the ZipArchive object.
archive:Dispose(). //Releases all resources used by the ZipArchive object.
end finally.
end procedure.
/* ************************ Function Implementations ***************** */
function IsFileLocked returns logical private
( input sourceFile as character ):
/*------------------------------------------------------------------------------
Purpose: TEst to see if a file is locked by another process
Notes:
------------------------------------------------------------------------------*/
define variable fs as class FileStream no-undo.
fs = System.IO.File:Open(sourceFile, FileMode:Open, FileAccess:Read, FileShare:None).
return false.
catch IOe as System.IO.IOException:
//message IOe:message.
return true.
end catch.
catch e1 as Progress.Lang.Error :
return true.
end catch.
finally:
if valid-object(fs) then
do:
fs:Close().
delete object fs.
end.
end finally.
end function.