BaseFile Manual

内容表

关于

BaseFile is a class to create arbitrary files and/or read and write data from and to files. In addition to functions reading and writing Cinema 4D data types, there are functions to do low-level byte accesses and to retrieve basic information on files.

Internally a BaseFile object keeps track of a read/write pointer, basically the position of the file, where data is read from with the next read access or written to with the next write access. The initial position of this read/write pointer depends on the mode used to open the file.

In general there are two fundamentally different ways to work with BaseFile :

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

This looks like so:

// Small helper function used in BaseFile 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 BaseFile * const file, const maxon::String & errText, Bool verbose = false ); static maxon::Result<void> PrintFileError( const Filename & fn, const BaseFile * const file, const maxon::String & errText, Bool verbose /*= false*/ ) { if (file == nullptr ) 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 ; }
注意
To delete a file see GeFKill() and the accompanying File Functions Manual .

Allocation/Deallocation

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

Opening and Closing

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

Read and Write

Most commonly 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 file and writing some typed data into it.

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

// Create the file with the purpose of writing into it. // BEWARE: FILEOPEN_WRITE will create a new file, any existing file will be overwritten. if (!file-> Open (fn, FILEOPEN::WRITE , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to create file" _s);

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

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

// This example demonstrates appending typed data to a file.

// Note: The file created via the "BaseFile Create" example is expected in this example. // BEWARE: This code will append data to the file, so be careful, when choosing one.

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

// Open a file with the purpose of appending some data to it. if (!file-> Open (fn, FILEOPEN::APPEND , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for appending" _s);

// Write some more data into the file. // Note: The order of data being written needs to be the same, when reading. if (!file-> WriteVector64 ( 向量 (10.0, 20.0, 30.0))) return PrintFileError(fn, file, "Failed to write a vector into file" _s);

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.
It is not recommended to mix these functions with the byte access functions (see Byte Access ).
// This example demonstrates reading typed data from a file.

// Note: The file created via the "BaseFile Create" or "BaseFile Append" examples is expected in this example.

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

// Open a file with the purpose of reading data from it. if (!file-> Open (fn, FILEOPEN::READ , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for reading" _s);

// Read data from file. // Note: The order needs to be the same as on write. Int32 value; if (!file-> ReadInt32 (&value)) return PrintFileError(fn, file, "Failed to read an Int32 from file" _s); if (value != 12345678) return PrintFileError(fn, file, "This is not the expected file" _s); ApplicationOutput ( "Int32 read from file: @" _s, value); maxon::String myText; if (!file-> ReadString (&myText)) return PrintFileError(fn, file, "Failed to read from string into file" _s); ApplicationOutput ( "String read from file: @" _s, myText); 向量 vec; if (!file-> ReadVector64 (&vec)) return PrintFileError(fn, file, "Failed to read Vector from file (maybe the append example hasn't been executed)" _s); ApplicationOutput ( "Vector read from file: @" _s, vec);

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

Byte Access

This is used to read or write files of arbitrary type/structure. For example, if a pure ASCII text file is supposed to be created, the above functions won't work, because no matter what is done (e.g. WriteString(), WriteChar()), there will always be the value headers prepended to the actual data. In such cases the byte access functions may be helpful.

A typical read or write looks like this:

警告
The byte sequences read or written are not platform independent. For example, when reading the four bytes of an Int32, one will need to know, if the most or the least significant byte is first.
// This example demonstrates reading raw bytes from a file.

// Typical first bytes of a Cinema 4D scene file (.c4d), just used as an example here. Nobody should rely on this! static const Char testBytes[] = { 'Q' , 'C' , '4' , 'D' , 'C' , '4' , 'D' }; const Int32 numBytes = sizeof (testBytes); Filename fn;

// Let user select a file if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::LOAD , "Select a C4D scene file..." _s)) return maxon::OK ; AutoAlloc<BaseFile> file; if (file == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Open a file with the purpose of reading data from it. if (!file-> Open (fn, FILEOPEN::READ , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for reading" _s);

// Read data from file. Char readBytes[numBytes]; const Bool justTry = false ; // Throw an error, if the file is smaller than the number of requested bytes. if (!file-> ReadBytes (&readBytes, sizeof (readBytes), justTry)) return PrintFileError(fn, file, maxon::String ( "Failed to read @ bytes from file" _s + maxon::String::IntToString(numBytes) + " bytes from file" _s));

// Compare the read bytes. Bool ok = true ; for ( Int32 idxByte = 0; idxByte < numBytes; ++idxByte) { if (readBytes[idxByte] != testBytes[idxByte]) { ok = false ; break ; } } if (ok) ApplicationOutput ( "The file seems to be a C4D scene file." ); else ApplicationOutput ( "The file does not seem to be a C4D scene file." );

// This example demonstrates writing raw bytes to a file. const maxon::String text = "The quick brown cube jumps over the sphere." _s;

// Let user select a directory. Filename fn; if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::DIRECTORY , "Select a directory for a new file..." _s)) return maxon::OK ; fn += Filename ( "myTextFile.txt" _s); AutoAlloc<BaseFile> file; if (file == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Open a file with the purpose of writing data to it. if (!file-> Open (fn, FILEOPEN::WRITE , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for writing" _s);

// Get a byte representation of the string (commented lines for classic String). //const Int32 numBytes = text.GetCStringLen(); const Int numBytes = text.GetLength(); //Char* cText = text.GetCStringCopy(); //maxon::Block<Char> textBuffer[numBytes]; //text.GetCStringBlock(&textBuffer); maxon::BaseArray<Char> cText = text.GetCString() iferr_return ; if (!cText. GetFirst ()) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION , "Error: Failed to get C string" _s);

// Write data to file if (!file-> WriteBytes (cText. GetFirst (), numBytes)) return PrintFileError(fn, file, "Failed to write " _s + maxon::String::IntToString(numBytes) + " bytes to file" _s);

//DeleteMem(cText); // Don't forget to free the memory of the C string.

// This example demonstrates seeking a position in a file.

// Let user select a file. Filename fn; if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::LOAD , "Select the file from BaseFile Write example..." _s)) return maxon::OK ; AutoAlloc<BaseFile> file; if (file == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Open a file with the purpose of reading/writing data from/to it. if (!file-> Open (fn, FILEOPEN::READWRITE , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for reading/writing" _s);

// Prove: After opening position is zero. // Note: This is different, if the file is opened with FILEOPEN::APPEND. ApplicationOutput ( "File opened with FILEOPEN_READWRITE, position: @" _s, file-> GetPosition ());

// Change read/write position. // Assuming the file from the BaseFile Write (RAW) example is used, skipping three bytes should point to the space before "quick". if (!file-> Seek (3)) return PrintFileError(fn, file, "Failed to seek position 3" _s); ApplicationOutput ( "Reading from position: @" _s, file-> GetPosition ());

// Read a few bytes // Assuming the file from the BaseFile Write (RAW) example is used, reading six bytes should read " quick" (including preceding space). Char word[7]; // Have buffer one byte larger than needed. if (!file-> ReadBytes (word, sizeof (word) - 1, false )) return PrintFileError(fn, file, "Failed to read six bytes" _s); word[6] = 0; // Assure zero terminated string.

// Now, change position to the end of the file in order to append the word just read. if (!file-> Seek (file-> GetLength (), FILESEEK::START )) // using absolute position in file return PrintFileError(fn, file, "Failed to seek end of file" _s); ApplicationOutput ( "Writing \"@\"to end of file, position: @" _s, word, file-> GetPosition ());

// Write the read word at the end of the file. if (!file-> WriteBytes (word, sizeof (word))) return PrintFileError(fn, file, "Failed to append bytes to the end of file" _s);

注意
It is possible to seek beyond the end of a file. When writing to this position, the skipped parts of the file will be filled with zeroes. A read from such position will end up in an error.

Utility

These utility functions provide some information on the file. Especially BaseFile::GetError() is frequently used to get information, what went wrong, if an error occured with one of the above functions.

// This example demonstrates accessing some file information.

// Let user select a file. Filename fn; if (!fn. FileSelect ( FILESELECTTYPE::ANYTHING , FILESELECT::LOAD , "Select a C4D scene file..." _s)) return maxon::OK ; AutoAlloc<BaseFile> file; if (file == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );

// Open the file if (!file-> Open (fn, FILEOPEN::READ , FILEDIALOG::ANY , BYTEORDER::V_INTEL , MACTYPE_CINEMA , MACCREATOR_CINEMA )) return PrintFileError(fn, file, "Failed to open the file for reading" _s);

// Print some infos about the file. const Int64 fileSize = file-> GetLength (); const LOCATION fileLocation = file-> GetLocation (); ApplicationOutput ( "File size: @bytes" _s, fileSize); switch (fileLocation) { case LOCATION::DISK : ApplicationOutput ( "File is located on disk" _s); break ; case LOCATION::IPCONNECTION : ApplicationOutput ( "File is located on a network device" _s); // Note: This is a special case, that can't occur in this situation. break ; case LOCATION::MEMORY : ApplicationOutput ( "File is located in memory" _s); // Note: This is a special case, see MemoryFileStruct manuals and examples. break ; }

延伸阅读

BaseFile::Close
Bool Close()
FILESELECT::DIRECTORY
@ DIRECTORY
Folder selection dialog.
BaseFile::WriteInt32
Bool WriteInt32(Int32 v)
FILEERROR::OUTOFMEMORY
@ OUTOFMEMORY
Not enough memory.
BaseFile::GetPosition
Int64 GetPosition()
BaseFile::GetLength
Int64 GetLength()
BaseFile::ReadString
Bool ReadString(maxon::String *v)
BaseFile::GetError
FILEERROR GetError() const
Int
maxon::Int Int
定义: ge_sys_math.h:62
BaseFile::ReadInt32
Bool ReadInt32(Int32 *v)
MACTYPE_CINEMA
#define MACTYPE_CINEMA
Standard Mac type code for Cinema 4D.
定义: ge_prepass.h:30
LOCATION::DISK
@ DISK
Disk storage.
FILEDIALOG::ANY
@ ANY
Show an error dialog for any error.
BaseFile
定义: c4d_file.h:330
BaseFile::ReadVector64
Bool ReadVector64(Vector64 *v)
BaseFile::ReadBytes
Int ReadBytes(void *data, Int len, Bool just_try_it=false)
maxon::String
定义: string.h:1197
BYTEORDER::V_INTEL
@ V_INTEL
Intel, little endian.
Filename
Manages file and path names.
定义: c4d_file.h:93
maxon::OK
return OK
定义: apibase.h:2532
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< Char >
BaseFile::Open
Bool Open(const Filename &name, FILEOPEN mode=FILEOPEN::READ, FILEDIALOG error_dialog=FILEDIALOG::IGNOREOPEN, BYTEORDER order=BYTEORDER::V_MOTOROLA, Int32 type='C4DC', Int32 creator='C4D1')
Filename::GetString
String GetString(void) const
BaseFile::WriteBytes
Bool WriteBytes(const void *data, Int len)
maxon::Result< void >
FILEOPEN::WRITE
@ WRITE
maxon::Vec3< maxon::Float64, 1 >
LOCATION::MEMORY
@ MEMORY
Target is a memory location.
FILEERROR::NONE
@ NONE
No error.
LOCATION::IPCONNECTION
@ IPCONNECTION
Target is IP connection.
FILEERROR
FILEERROR
定义: ge_prepass.h:3729
Int32
maxon::Int32 Int32
定义: ge_sys_math.h:58
FILEOPEN::READWRITE
@ READWRITE
Open the file for both reading and writing.
BaseFile::WriteString
Bool WriteString(const maxon::String &v)
ApplicationOutput
#define ApplicationOutput(formatString,...)
定义: debugdiagnostics.h:207
LOCATION
LOCATION
定义: ge_prepass.h:3769
FILESEEK::START
@ START
The position is given relative to the start of the file.
BaseFile::Seek
Bool Seek(Int64 pos, FILESEEK mode=FILESEEK::RELATIVE_)
MACCREATOR_CINEMA
#define MACCREATOR_CINEMA
Standard Mac creator code for Cinema 4D.
定义: ge_prepass.h:31
FILESELECT::LOAD
@ LOAD
Load dialog.
FILEOPEN::READ
@ READ
Open the file for reading.
BaseFile::WriteVector64
Bool WriteVector64(const Vector64 &v)
FILEOPEN::APPEND
@ APPEND
Open an existing file for writing and set the position to the end of that file.
AutoAlloc
定义: ge_autoptr.h:36
Int64
maxon::Int64 Int64
定义: ge_sys_math.h:60
Bool
maxon::Bool Bool
定义: ge_sys_math.h:53
BaseFile::GetLocation
LOCATION GetLocation() const
Char
maxon::Char Char
定义: ge_sys_math.h:54
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