内容表
关于
The
ZipFile
class provides means to work with ZIP archives. ZIP files can be created, modified and extracted.
-
注意
-
To create ZIP archives with the
MAXON API
see
Archives Manual
.
Allocation/Deallocation
ZipFile
objects are created with the usual tools, see
Entity Creation and Destruction Manual (Classic)
.
Opening and Closing
Filename
Metadata
Compression Level
CRC
Extracting an Entire Archive
// This example demonstrates extracting the selected ZIP file to a given folder.
Filename
fnZip, fnDest;
if
(!fnZip.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::LOAD
,
"Choose a ZIP file to extract..."
_s,
"zip"
_s))
return
maxon::OK
;
if
(!fnDest.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::DIRECTORY
,
"Choose a directory to extract to..."
_s))
return
maxon::OK
;
AutoAlloc<ZipFile>
zf;
if
(zf ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
if
(!zf->
ExtractToDirectory
(fnZip, fnDest))
return
maxon::UnknownError(
MAXON_SOURCE_LOCATION
);
Current File
Internally the
ZipFile
class has a pointer to the "current" file inside of the archive. The following functions provide means to change the current file pointer to another file or directory.
// This example iterates the files in ZIP archive and finds the first C4D scene (if any).
Bool
sceneFound =
false
;
UInt32
fileSizeUncompressed = 0;
if
(!zf->
GoToFirstFile
())
return
PrintMsgAndCloseZipFile(zf,
"Error: No files in ZIP archive."
);
// small custom helper function
do
{
// Break loop, as soon as the first scene file is encountered.
ZipFileInfo
zfi;
String
sName;
if
(zf->
GetCurrentFileInfo
(zfi) && !(zfi.
lFlags
&
ZIP_FLAG_DIRECTORY
) && zf->
GetCurrentFileInfo
(&sName) &&
Filename
(sName).CheckSuffix(
"c4d"
_s))
{
fileSizeUncompressed = zfi.
lUncompressedSize
;
sceneFound =
true
;
break
;
}
}
while
(zf->
GoToNextFile
());
if
(!sceneFound || fileSizeUncompressed == 0)
return
PrintMsgAndCloseZipFile(zf,
"Error: No C4D scene found in archive."
);
// small custom helper function
The current file can be extracted from a ZIP archive:
// This example demonstrates looping through the files of a ZIP file and extract each of them separately.
Filename
fnZip, fnDest;
if
(!fnZip.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::LOAD
,
"Choose a ZIP file to extract files from..."
_s))
return
maxon::OK
;
if
(!fnDest.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::DIRECTORY
,
"Choose a destination directory for the extracted files..."
_s))
return
maxon::OK
;
AutoAlloc<ZipFile>
zf;
if
(zf ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
if
(!zf->
Open
(fnZip,
true
))
// Open for reading.
return
maxon::UnknownError(
MAXON_SOURCE_LOCATION
);
// Iterate files and extract one by one.
if
(!zf->
GoToFirstFile
())
{
ApplicationOutput
(
"No files in ZIP archive."
);
zf->
关闭
();
return
maxon::OK
;
}
do
{
// Extract only files (just to demonstrate, that directory structure from archive will stay intact nevertheless).
ZipFileInfo
zfi;
if
(zf->
GetCurrentFileInfo
(zfi) && !(zfi.
lFlags
&
ZIP_FLAG_DIRECTORY
))
zf->
ExtractCurrentFile
(fnDest);
}
while
(zf->
GoToNextFile
());
ShowInFinder
(fnDest,
false
);
zf->
关闭
();
Comprehensive information can be retrieved for the current file:
Similar to "normal" files (e.g.
BaseFile
) the current file can be opened for reading:
// This example reads the current file in chunks from a ZIP archive.
// Open the file.
if
(!zf->
OpenCurrentFile
())
return
PrintMsgAndCloseZipFile(zf,
"Error: Failed to open current file in archive."
);
// small custom helper function
// Allocate a buffer to read the file into.
maxon::AutoMem<Char>
buffer =
NewMemClear
(
Char
, fileSizeUncompressed)
iferr_ignore
(
"nullptr check next"
);
if
(buffer ==
nullptr
)
return
PrintMsgAndCloseZipFile(zf,
"Error: Failed to open allocate buffer."
);
// small custom helper function
// Reading in chunks of 4096 (0x1000) bytes, just for demonstration purposes.
const
Int32
maxChunkSize = 0x1000;
Char
* bufferCurrentPos = buffer;
Char
*
const
bufferEnd = buffer.
GetPointer
() + fileSizeUncompressed;
// Points to the first byte behind the allocated buffer.
while
(!zf->
EndOfCurrentFile
())
{
const
Int32
chunkSize =
ClampValue
((
Int32
)(bufferEnd - bufferCurrentPos), 0, maxChunkSize);
if
(chunkSize <= 0)
break
;
const
Int32
numBytesRead = zf->
ReadCurrentFile
(bufferCurrentPos, chunkSize);
if
(numBytesRead < 0)
break
;
bufferCurrentPos += numBytesRead;
}
if
(!zf->
EndOfCurrentFile
() || (bufferCurrentPos != bufferEnd))
{
return
PrintMsgAndCloseZipFile(zf,
"Error: Something went wrong, while reading file from archive."
);
// small custom helper function
}
zf->
CloseCurrentFile
();
zf->
关闭
();
Add to an ZIP File
// This example demonstrates how a ZIP file is created and files are added.
Filename
fnZip;
if
(!fnZip.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::SAVE
,
"Save Zip File"
_s))
return
maxon::OK
;
AutoAlloc<ZipFile>
zf;
if
(zf ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
if
(!zf->
Open
(fnZip,
false
,
ZIP_APPEND_CREATE
))
return
maxon::UnknownError(
MAXON_SOURCE_LOCATION
);
Filename
fnCopy;
while
(fnCopy.
FileSelect
(
FILESELECTTYPE::ANYTHING
,
FILESELECT::LOAD
,
"Select file to add to Zip File"
_s))
{
zf->
CopyInFileInZip
(fnCopy, fnCopy.
GetFileString
());
}
zf->
关闭
();
延伸阅读
@ DIRECTORY
Folder selection dialog.
Bool ExtractCurrentFile(const Filename &fnDir, BaseThread *pThread, Int32 lFlags=0x00000001, const char *pchPassword=nullptr, Filename *pfnDest=nullptr)
#define NewMemClear(T, cnt)
定义:
defaultallocator.h:205
maxon::UInt32 UInt32
定义:
ge_sys_math.h:59
Bool CopyInFileInZip(const Filename &fn, const String &str, const char *pchPassword=nullptr)
UInt32 lUncompressedSize
Uncompressed size.
定义:
lib_zipfile.h:81
Manages file and path names.
定义:
c4d_file.h:93
return OK
定义:
apibase.h:2532
UInt32 lFlags
Flags: ZIP_FLAG.
定义:
lib_zipfile.h:76
#define MAXON_SOURCE_LOCATION
定义:
memoryallocationbase.h:66
Int32 ReadCurrentFile(void *pBuffer, UInt32 lBufferSize)
Bool ExtractToDirectory(const Filename &fnZip, const Filename &fnDir, Int32 lFlags=0x00000001, ExtractDirectoryCallback fn=nullptr, void *pData=nullptr, const char *pChPassword=nullptr)
#define ZIP_FLAG_DIRECTORY
Directory flag.
定义:
lib_zipfile.h:21
#define iferr_ignore(...)
定义:
resultbase.h:1399
Bool GetCurrentFileInfo(ZipFileInfo &i)
Bool OpenCurrentFile(const char *pChPassword=nullptr)
String GetFileString(void) const
Bool ShowInFinder(const Filename &fn, Bool open)
T * GetPointer()
定义:
baseref.h:83
maxon::Int32 Int32
定义:
ge_sys_math.h:58
#define ApplicationOutput(formatString,...)
定义:
debugdiagnostics.h:207
#define ZIP_APPEND_CREATE
Creates a new ZIP file.
定义:
lib_zipfile.h:132
Bool Open(const Filename &fn, const Bool bRead, const Int32 lAppend=0)
maxon::Bool Bool
定义:
ge_sys_math.h:53
X ClampValue(X value, X lowerLimit, X upperLimit)
Clips a value against a lower and upper limit. The new value is returned.
定义:
apibasemath.h:221
maxon::Char Char
定义:
ge_sys_math.h:54
Bool FileSelect(FILESELECTTYPE type, FILESELECT flags, const maxon::String &title, const maxon::String &force_suffix=maxon::String())