HyperFile Manual

内容表

关于

HyperFile is a class to read and write data to a file on disk. This class is for example used to store Cinema 4D scenes, but can also be used to create individual files storing Cinema 4D data types. A HyperFile can not be used to create arbitrary files (like e.g. text files) as all data stored in a HyperFile is prefixed with a value header describing the stored data, see BaseFile Manual on Byte Access instead.

HyperFile class makes many things easier compared to BaseFile class (e.g. one does not need to care about byte order), while sacrificing some of the power of the low-level functions provided there (no byte access possible, no repositioning of the read/write pointer). Most advantageous compared to BaseFile is the file versioning and chunk handling.

A HyperFile is always read (and also written) from the beginning of the file and the handling of the read/write pointer is handled completely internally. In theory replacing of parts of the data in a HyperFile is possible, but definitely not recommended, as good knowledge of the internal structure is needed to not corrupt the file.

注意
To delete a file see GeFKill() and the accompanying File Functions Manual .
Besides the code snippets shown on this page, there's also the hyperfile_objectdata example in cinema4dsdk.

Throughout this page the code snippets use a helper function PrintFileError() .

This looks like so:

// Small helper function used in HyperFile code snippets below. // Depending on verbose parameter a file error (if any) will also be decoded to a human readable string. // Can also be used, when there's no HyperFile (e.g. HyperFile allocation failed), then only the filename will be used. // It returns true, if there was no error, otherwise false. // In this way it can be used in snippets to directly return from the calling function. static maxon::Result<void> PrintFileError( const Filename & fn, const HyperFile * const file, const maxon::String & errText, Bool verbose = false ); static maxon::Result<void> PrintFileError( const Filename & fn, const HyperFile * const file, const maxon::String & errText, Bool verbose /*= false*/ ) { if (!file) return maxon::NullptrError( MAXON_SOURCE_LOCATION );
if (verbose) { return FileErrorToString(file); // FileErrorToString() is a custom function. } else { const FILEERROR err = file-> GetError (); maxon::String errString = "Error (" _s + maxon::String::IntToString(( Int )err) + "): " _s + errText + ": " _s + maxon::String (fn. GetString ());
if (err != FILEERROR::NONE ) { if (err == FILEERROR::OUTOFMEMORY ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION , errString); else if (err == FILEERROR::UNKNOWN_VALUE ) return maxon::UnknownError( MAXON_SOURCE_LOCATION , errString); else return maxon::UnexpectedError( MAXON_SOURCE_LOCATION , errString); } } ApplicationOutput ( "No error: &" _s, maxon::String (fn. GetString ())); return maxon::OK ; }

Access

A HyperFile argument is typically provided in NodeData::Read() and NodeData::Write() functions. See NodeData::Read() / NodeData::Write() Manual .

Allocation/Deallocation

HyperFile objects are created with the usual tools, see Entity Creation and Destruction Manual (Classic) .

Open and Close

After allocating a HyperFile object HyperFile::Open() needs to be called to bind it to a file in the filesystem (either an existing or a new one).

注意
A HyperFile is always read and written from the beginning of a file. So FILEOPEN::APPEND can NOT be used with a HyperFile , appending is not supported.

Read and Write

The following functions are used to store data in a "BaseContainer"-like fashion, where one does not need to worry about the size of datatypes or positioning the read/write pointer.

A Typical Write Access

注意
The order of write accesses will determine the order of read accesses (the order will need to be the same).
// This example demonstrates creating a new HyperFile and writing some typed data into it. Filename fn;

// Let user select a target directory. if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::DIRECTORY , "Select a directory..." _s)) return maxon::OK ; fn += Filename { "myhyperfile.dat" }; AutoAlloc<HyperFile> hf; if (!hf) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Create a HyperFile with the purpose of writing into it. // BEWARE: FILEOPEN_WRITE will create a new file, any existing file will be overwritten. const Int32 ident = 42; // Set an ID for the new file, use a/the plugin ID to define a unique file type. if (!hf-> Open (ident, fn, FILEOPEN::WRITE , FILEDIALOG::ANY )) return PrintFileError(fn, hf, "Failed to create HyperFile" _s);

// Write some data into the new HyperFile. // Note: The order of data being written needs to be the same, when reading. if (!hf-> WriteInt32 (12345678)) return PrintFileError(fn, hf, "Failed to write an Int32 into HyperFile" _s); if (!hf-> WriteString ( "Hello World!" _s)) return PrintFileError(fn, hf, "Failed to write a String into HyperFile" _s);

// Finally close the HyperFile. // Note: Actually not needed, as the file will be closed on destruction of the HyperFile object. hf-> 关闭 ();

A Typical Read Access

All of the following read/write functions automatically take care of the read/write pointer (i.e. advancing it by the correct amount of bytes depending on the access type) and are able to detect access with wrong data type. Internally this is achieved by not only writing the actual data to the file, but also an additional value header preceding each data, specifying the type and also (where needed) the amount of data.

注意
The order of read accesses has to match the order of write accesses.
These functions can not be used to read data from an arbitrary file, but only from files created by Cinema 4D , when data got written by the respective write functions.
// This example demonstrates reading simple typed data from a HyperFile.

// Note: The file created via the "HyperFile Create" example is expected in this example. Filename fn;

// Let user select a file. if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::LOAD , "Select the file from the HyperFile Create or Append command..." _s)) return maxon::OK ; AutoAlloc<HyperFile> hf; if (!hf) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Open a HyperFile with the purpose of reading data from it. const Int32 ident = 42; // The ID of the file (-type) that's supposed to be opened. if (!hf-> Open (ident, fn, FILEOPEN::READ , FILEDIALOG::ANY )) return PrintFileError(fn, hf, "Failed to open the HyperFile for reading" _s);

// Read data from file. // Note: The order needs to be the same as on write. Int32 value; if (!hf-> ReadInt32 (&value)) return PrintFileError(fn, hf, "Failed to read an Int32 from HyperFile" _s); if (value != 12345678) return PrintFileError(fn, hf, "This is not the expected HyperFile" _s); ApplicationOutput ( "Int32 read from HyperFile: @" _s, value); maxon::String myText; if (!hf-> ReadString (&myText)) return PrintFileError(fn, hf, "Failed to read a String from HyperFile" _s); ApplicationOutput ( "String read from HyperFile: @" _s, myText);

As mentioned in the beginning, data/values get stored inside the HyperFile as a pair consisting of a describing header followed by the actual data. With the following functions the type of the next value can be detected (see HYPERFILEVALUE_... defines below) and the value may also be skipped (i.e. continue reading with the next value). Usually this is not needed, but can be helpful if for example writing a loop reading arbitrary values.

Char

另请参阅 Primitive Data Types Manual (Classic) on Char .

String

另请参阅 String Manual (Classic) .

Filename

另请参阅 Filename Manual .

Bool

另请参阅 Primitive Data Types Manual (Classic) on Bool .

整数

另请参阅 Primitive Data Types Manual (Classic) on 整数 .

Float

另请参阅 Primitive Data Types Manual (Classic) on Float .

向量

另请参阅 Vector Manual (Classic) .

矩阵

另请参阅 Matrix Manual (Classic) .

Arrays

These functions can be used with standard C arrays:

// This example reads a C array from a HyperFile. Float64 arrFloat[4] = { 0.0 }; const Int arrSize = sizeof (arrFloat) / sizeof ( Float64 ); if (!hf-> ReadArray (arrFloat, HYPERFILEARRAY::REAL , sizeof ( Float64 ), arrSize)) return PrintFileError(fn, hf, "Failed to read array (Float64) from HyperFile" _s); ApplicationOutput ( "Array (Float64) read from HyperFile:" _s); for ( Int32 idx = 0; idx < arrSize; ++idx) { ApplicationOutput ( " @" , arrFloat[idx]); }

// This example writes a standard C array to a HyperFile. const Float64 arrFloat[4] = { 42.0, PI , LIMIT<Float64>::MAX , ( Float64 )1.0 / ( Float64 )255.0 }; // just an example array with four Float64 values const Int arrSize = sizeof (arrFloat) / sizeof ( Float64 ); if (!hf-> WriteArray (arrFloat, HYPERFILEARRAY::REAL , sizeof ( Float64 ), arrSize)) return PrintFileError(fn, hf, "Failed to write an array (Float64) into HyperFile" _s);

And also with maxon::BaseArray :

// This example reads a BaseArray from a HyperFile. maxon::BaseArray<Int64> arrInt; arrInt. Resize (4) iferr_return ; // Make sure, the BaseArray has enough space to hold the data to be read (otherwise read entry by entry and Append()). DebugAssert (arrInt. GetCount () < LIMIT<Int32>::MAX ); // Read array's count parameter is only Int32.

// A BaseArray stores data in a continguous memory block, the start address is returned by BaseArray::GetFirst(). if (!hf-> ReadArray (arrInt. GetFirst (), HYPERFILEARRAY::LLONG , sizeof ( Int64 ), ( Int32 )arrInt. GetCount ())) return PrintFileError(fn, hf, "Failed to read BaseArray<Int64> from HyperFile" _s); ApplicationOutput ( "BaseArray<Int64> read from HyperFile:" _s); for ( auto val : arrInt) { ApplicationOutput ( " @" , val); }

// This example writes a BaseArray to a HyperFile. maxon::BaseArray<Int64> arrInt; // just an example BaseArray with arbitrary values arrInt. Append (42) iferr_return ; arrInt. Append (1984) iferr_return ; arrInt. Append (2001) iferr_return ; arrInt. Append ( LIMIT<Int64>::MAX ) iferr_return ;

// A BaseArray stores data in a continguous memory block, the start address is returned by BaseArray::GetFirst(). if (!hf-> WriteArray (arrInt. GetFirst (), HYPERFILEARRAY::LLONG , sizeof ( Int64 ), ( Int32 )arrInt. GetCount ())) return PrintFileError(fn, hf, "Failed to write a BaseArray (Int64) into HyperFile" _s);

GeData

// This example reads GeData from a HyperFile. GeData d; if (!hf-> ReadGeData (&d)) return PrintFileError(fn, hf, "Failed to read a GeData from HyperFile" _s); if (d. GetType () == DTYPE_VECTOR ) // In the write example, a vector was written as GeData, so lets verify. ApplicationOutput ( "GeData(Vector) read from HyperFile: @" , d. GetVector ()); // This example writes GeData to a HyperFile. GeData d; d. SetVector ( 向量 { 10.0, 20.0, 30.0 }); if (!hf-> WriteGeData (d)) return PrintFileError(fn, hf, "Failed to write a GeData(Vector) into HyperFile" _s);

另请参阅 GeData Manual .

BaseContainer

另请参阅 BaseContainer Manual .

BaseTime

另请参阅 BaseTime 手册 .

BaseBitmap

另请参阅 BaseBitmap Manual .

Raw Memory

注意
Only use when really needed. Be aware that the byte sequences will not be platform independent.
// Following HyperFile::ReadMemory() and HyperFile:WriteMemory() code snippets use this structure. struct myStructure { Float64 myFloat; Int64 myInt; Bool myBool; };

// This example reads some arbitrary data (in this case the struct stored earlier on) from a HyperFile.

void * data; Int size = 0; if (!hf-> ReadMemory (&data, &size)) return PrintFileError(fn, hf, "Failed to read memory (myStructure) from HyperFile" _s); myStructure* const myData = static_cast< myStructure* > (data); // Interpret the read data as struct. ApplicationOutput ( "Memory (myStructure, size: @ ) read from HyperFile:" _s, size); ApplicationOutput ( " @" , myData->myFloat); ApplicationOutput ( " @" , myData->myInt); ApplicationOutput ( " @" , myData->myBool); // This example writes a C structure to a HyperFile. myStructure someData; someData.myFloat = 0.5; someData.myInt = 42; someData.myBool = true ; if (!hf-> WriteMemory (&someData, sizeof (someData))) return PrintFileError(fn, hf, "Failed to write an memory (myStructure) into HyperFile" _s);

Uuid

Chunk

Chunks provide means to group or organize several values. This can be useful if for example different versions of a plugin store different sets of parameters, so a parameter set no longer understood can be skipped.

Utility

Error

文件版本

Other HyperFile Related Functions

Actually not part of the HyperFile class, these convenience functions can be used to read or write a complete GeListNode from/into a single HyperFile referenced by Filename .

// This example demonstrates reading a GeListNode (in this case an object) from a HyperFile (created by the code snippet on WriteHyperFile() below). Filename fn;

// Let user select a directory to save to. if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::LOAD , "Select a file created by HyperFile ReadHyperFile example..." _s)) return maxon::OK ; AutoAlloc<BaseObject> op { Onull }; if (!op) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); maxon::String errString = "" _s; if ( ReadHyperFile (doc, op, fn, 123456, &errString) != FILEERROR::NONE ) // Note: ident has to match in WriteHyperFile(), get a unique plugin ID! return PrintFileError(fn, nullptr , "Failed to write object " _s + maxon::String (op-> GetName ()) + " to file (" _s + errString + "): " _s); doc-> InsertObject (op.Release(), nullptr , nullptr ); // Note: Usage of Release(), when inserting the AutoAlloc'ed object into the scene.

// This example demonstrates writing a GeListNode (in this case the active object) into a separate HyperFile. Filename fn;

// Let user select a directory to save to. if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::DIRECTORY , "Select a path for saving..." _s)) return maxon::OK ; fn += Filename { maxon::String (op-> GetName ()) + ".myobj" _s };

// Write the object to the HyperFile. if ( WriteHyperFile (doc, op, fn, 123456) != FILEERROR::NONE ) // Note: ident has to match in ReadHyperFile(), get a unique plugin ID! return PrintFileError(fn, nullptr , "Failed to write object " _s + maxon::String { op-> GetName () } + " to file: " _s); ApplicationOutput ( "Successfully saved to file: " _s + maxon::String { fn. GetString () });

延伸阅读

FILESELECT::DIRECTORY
@ DIRECTORY
Folder selection dialog.
WriteHyperFile
FILEERROR WriteHyperFile(BaseDocument *doc, GeListNode *node, const Filename &filename, Int32 ident)
FILEERROR::OUTOFMEMORY
@ OUTOFMEMORY
Not enough memory.
HyperFile::WriteString
Bool WriteString(const maxon::String &v)
BaseDocument::InsertObject
void InsertObject(BaseObject *op, BaseObject *parent, BaseObject *pred, Bool checknames=false)
Int
maxon::Int Int
定义: ge_sys_math.h:62
GeData::GetType
Int32 GetType(void) const
定义: c4d_gedata.h:407
FILEDIALOG::ANY
@ ANY
Show an error dialog for any error.
GeData::SetVector
void SetVector(const Vector &v)
定义: c4d_gedata.h:598
Onull
#define Onull
Null.
定义: ge_prepass.h:1009
maxon::String
定义: string.h:1197
Filename
Manages file and path names.
定义: c4d_file.h:93
maxon::OK
return OK
定义: apibase.h:2532
HyperFile::GetError
FILEERROR GetError() const
HyperFile::ReadArray
Bool ReadArray(void *data, HYPERFILEARRAY type, Int32 structure_increment, Int32 count)
maxon::BaseArray::Resize
ResultMem Resize(Int newCnt, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::DEFAULT)
定义: basearray.h:1077
FILESELECTTYPE::ANYTHING
@ ANYTHING
Any file.
maxon::BaseArray::GetFirst
const MAXON_ATTRIBUTE_FORCE_INLINE T * GetFirst() const
定义: basearray.h:1034
iferr_return
#define iferr_return
定义: resultbase.h:1434
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
定义: memoryallocationbase.h:66
maxon::BaseArray< Int64 >
HyperFile::WriteInt32
Bool WriteInt32(Int32 v)
HyperFile::Open
Bool Open(Int32 ident, const Filename &filename, FILEOPEN mode, FILEDIALOG error_dialog)
Filename::GetString
String GetString(void) const
HYPERFILEARRAY::REAL
@ REAL
Float array.
maxon::Result< void >
FILEOPEN::WRITE
@ WRITE
HyperFile::ReadInt32
Bool ReadInt32(Int32 *v)
maxon::BaseArray::GetCount
MAXON_ATTRIBUTE_FORCE_INLINE Int GetCount() const
定义: basearray.h:527
maxon::BaseArray::Append
MAXON_ATTRIBUTE_FORCE_INLINE ResultRef< T > Append()
定义: basearray.h:569
maxon::Vec3< maxon::Float64, 1 >
DTYPE_VECTOR
@ DTYPE_VECTOR
向量
定义: lib_description.h:70
HyperFile::ReadMemory
Bool ReadMemory(void **data, Int *size)
HyperFile::WriteMemory
Bool WriteMemory(const void *data, Int count)
PI
PI
定义: unicodeutils.h:18
LIMIT
定义: apibasemath.h:33
HyperFile::WriteGeData
Bool WriteGeData(const GeData &v)
FILEERROR::NONE
@ NONE
No error.
GeData
定义: c4d_gedata.h:82
FILEERROR
FILEERROR
定义: ge_prepass.h:3729
Int32
maxon::Int32 Int32
定义: ge_sys_math.h:58
HyperFile::ReadString
Bool ReadString(maxon::String *v)
HyperFile
定义: c4d_file.h:1069
ApplicationOutput
#define ApplicationOutput(formatString,...)
定义: debugdiagnostics.h:207
FILESELECT::LOAD
@ LOAD
Load dialog.
HYPERFILEARRAY::LLONG
@ LLONG
Int64 array.
FILEOPEN::READ
@ READ
Open the file for reading.
HyperFile::ReadGeData
Bool ReadGeData(GeData *v)
HyperFile::Close
Bool Close()
AutoAlloc
定义: ge_autoptr.h:36
HyperFile::WriteArray
Bool WriteArray(const void *data, HYPERFILEARRAY datatype, Int32 structure_increment, Int32 count)
Int64
maxon::Int64 Int64
定义: ge_sys_math.h:60
Bool
maxon::Bool Bool
定义: ge_sys_math.h:53
BaseList2D::GetName
String GetName() const
定义: c4d_baselist.h:2318
DebugAssert
#define DebugAssert(condition,...)
定义: debugdiagnostics.h:245
GeData::GetVector
const Vector & GetVector(void) const
定义: c4d_gedata.h:451
ReadHyperFile
FILEERROR ReadHyperFile(BaseDocument *doc, GeListNode *node, const Filename &filename, Int32 ident, maxon::String *warning_string)
Float64
maxon::Float64 Float64
定义: ge_sys_math.h:65
FILEERROR::UNKNOWN_VALUE
@ UNKNOWN_VALUE
Unknown value detected.
Filename::FileSelect
Bool FileSelect(FILESELECTTYPE type, FILESELECT flags, const maxon::String &title, const maxon::String &force_suffix=maxon::String())

Copyright  © 2014-2025 乐数软件    

工业和信息化部: 粤ICP备14079481号-1