TDirectoryFile*¶
v6.10.04
继承TDirectory
Describe directory structure in a ROOT file.
A ROOT file is structured in Directories (like a file system).Each Directory has a list of Keys (see TKeys) and a list of objects in memory. A Key is a small object that describes the type and location of a persistent object in a file. The persistent object may be a directory.
class¶
// TDirectory status bits
enum { kCloseDirectory = BIT(7) };
TDirectoryFile();
TDirectoryFile(const char *name, const char *title, Option_t *option="", TDirectory* motherDir = 0);
/// Create a new TDirectoryFile
/// A new directory with a name and a title is created in the current directory.
/// The directory header information is immediatly saved on the file
/// A new key is added in the parent directory.
/// When this constructor is called from a class directly derived
/// from TDirectoryFile, the third argument, classname, MUST be specified.
/// In this case, classname must be the name of the derived class.
/// Note that the directory name cannot contain slashes.
virtual ~TDirectoryFile();
virtual void Append(TObject *obj, Bool_t replace = kFALSE);
/// Append object to this directory.
/// If replace is true:
/// remove any existing objects with the same same (if the name is not ""
void Add(TObject *obj, Bool_t replace = kFALSE) { Append(obj,replace); }
Int_t AppendKey(TKey *key);/// Insert key in the linked list of keys of this directory.
virtual void Browse(TBrowser *b);/// Browse the content of the directory.
void Build(TFile* motherFile = 0, TDirectory* motherDir = 0);/// Initialise directory to defaults.
virtual TObject *CloneObject(const TObject *obj, Bool_t autoadd = kTRUE);
/// Make a clone of an object using the Streamer facility.
/// If the object derives from TNamed, this function is called
/// by TNamed::Clone. TNamed::Clone uses the optional argument newname to set
/// a new name to the newly created object.
/// If autoadd is true and if the object class has a
/// DirectoryAutoAdd function, it will be called at the end of the
/// function with the parameter gDirectory. This usually means that
/// the object will be appended to the current ROOT directory.
virtual void Close(Option_t *option="");/// Delete all objects from memory and directory structure itself.
virtual void Copy(TObject &) const { MayNotUse("Copy(TObject &)"); }
virtual Bool_t cd(const char *path = 0);
/// Change current directory to "this" directory.
/// Using path one can
/// change the current directory to "path". The absolute path syntax is:
/// file.root:/dir1/dir2
/// where file.root is the file and /dir1/dir2 the desired subdirectory
/// in the file. Relative syntax is relative to "this" directory. E.g:
/// ../aa. Returns kTRUE in case of success.
virtual void Delete(const char *namecycle="");
/// Delete Objects or/and keys in a directory
/// Properties of the namecycle string:
/// - namecycle has the format name;cycle
/// - namecycle = "" is same as namecycle ="T*"
/// - name = * means all
/// - cycle = * means all cycles (memory and keys)
/// - cycle = "" or cycle = 9999 ==> apply to a memory object
/// When name=* use T* to delete subdirectories also
/// To delete one directory, you must specify the directory cycle,
/// eg. file.Delete("dir1;1");
/// Examples:
/// | Pattern | Description |
/// |---------|-------------|
/// | foo | delete object named foo in memory |
/// | foo* | delete all objects with a name starting with foo |
/// | foo;1 | delete cycle 1 of foo on file |
/// | foo;* | delete all cycles of foo on file and also from memory |
/// | *;2 | delete all objects on file having the cycle 2 |
/// | *;* | delete all objects from memory and file |
/// | T*;* | delete all objects from memory and file and all subdirectories |
/// ## WARNING
/// If the key to be deleted contains special characters ("+","^","?", etc
/// that have a special meaning for the regular expression parser (see TRegexp)
/// then you must specify 2 backslash characters to escape the regular expression.
/// For example, if the key to be deleted is namecycle = "C++", you must call
/// mydir.Delete("C\\+\\+"));
virtual void FillBuffer(char *&buffer);
/// Encode directory header into output buffer
virtual TKey *FindKey(const char *keyname) const;
/// Find key with name keyname in the current directory
virtual TKey *FindKeyAny(const char *keyname) const;
/// Find key with name keyname in the current directory or
/// its subdirectories.
/// NOTE: that If a key is found, the directory containing the key becomes
/// the current directory
virtual TObject *FindObjectAny(const char *name) const;
/// Find object by name in the list of memory objects of the current
/// directory or its sub-directories.
/// After this call the current directory is not changed.
/// To automatically set the current directory where the object is found,
/// use FindKeyAny(aname)->ReadObj().
virtual TObject *FindObjectAnyFile(const char *name) const;
/// Scan the memory lists of all files for an object with name
virtual TObject *Get(const char *namecycle);
/// Return pointer to object identified by namecycle.
/// Properties:
/// - namecycle has the format name;cycle
/// - name = * is illegal, cycle = * is illegal
/// - cycle = "" or cycle = 9999 ==> apply to a memory object
/// Examples:
/// | Pattern | Explanation |
/// |---------|-------------|
/// | foo | get object named foo in memory if object is not in memory, try with highest cycle from file |
/// | foo;1 | get cycle 1 of foo on file |
/// The retrieved object should in principle derive from TObject.
/// If not, the function TDirectoryFile::GetObject should be called.
/// However, this function will still work for a non-TObject, provided that
/// the calling application cast the return type to the correct type (which
/// is the actual type of the object).
/// ### The GetObjectMethod
/// The method GetObject offers better protection and avoids the need
/// for any cast:
/// ~~~{.cpp}
/// MyClass *obj;
/// directory->GetObject("some object",obj);
/// if (obj) { ... the object exist and inherits from MyClass ... }
/// ~~~
/// ### Very important note about inheritance
/// In case the class of this object derives from TObject but not
/// as a first inheritance, one must use dynamic_cast<>().
/// #### Example 1 - Normal case:
/// class MyClass : public TObject, public AnotherClass
/// then on return, one can adopt a C style cast:
/// auto objPtr = (MyClass*)directory->Get("some object of MyClass");
/// #### Example 2 - Special case:
/// class MyClass : public AnotherClass, public TObject
/// then on return, one must do:
/// auto objPtr = dynamic_cast<MyClass*>(directory->Get("some object of MyClass"));
/// Of course, dynamic_cast<> can also be used in the example 1.
virtual TDirectory *GetDirectory(const char *apath, Bool_t printError = false, const char *funcname = "GetDirectory");
/// Find a directory named "apath".
/// It apath is null or empty, returns "this" directory.
/// Otherwise use the name "apath" to find a directory.
/// The absolute path syntax is:
/// file.root:/dir1/dir2
/// where file.root is the file and /dir1/dir2 the desired subdirectory
/// in the file. Relative syntax is relative to "this" directory. E.g:
/// ../aa.
/// Returns 0 in case path does not exist.
/// If printError is true, use Error with 'funcname' to issue an error message.
template <class T> inline void GetObject(const char* namecycle, T*& ptr) // See TDirectory::Get for information
{
ptr = (T*)GetObjectChecked(namecycle,TBuffer::GetClass(typeid(T)));
}
virtual void *GetObjectChecked(const char *namecycle, const char* classname);
/// See documentation of TDirectoryFile::GetObjectCheck(const char *namecycle, const TClass *cl)
virtual void *GetObjectChecked(const char *namecycle, const TClass* cl);
/// Return pointer to object identified by namecycle if and only if the actual
/// object is a type suitable to be stored as a pointer to a "expectedClass"
/// If expectedClass is null, no check is performed.
/// - namecycle has the format name;cycle
/// - name = * is illegal, cycle = * is illegal
/// - cycle = "" or cycle = 9999 ==> apply to a memory object
/// ### Very important note
/// The calling application must cast the returned pointer to
/// the type described by the 2 arguments (i.e. cl):
/// auto objPtr = (MyClass*)directory->GetObjectChecked("some object of MyClass","MyClass"));
/// Note: We recommend using the method TDirectoryFile::GetObject:
/// ~~~{.cpp}
/// MyClass *obj = nullptr;
/// directory->GetObject("some object inheriting from MyClass",obj);
/// if (obj) { ... we found what we are looking for ... }
/// ~~~
virtual void *GetObjectUnchecked(const char *namecycle);
/// Return pointer to object identified by namecycle.
/// The returned object may or may not derive from TObject.
/// - namecycle has the format name;cycle
/// - name = * is illegal, cycle = * is illegal
/// - cycle = "" or cycle = 9999 ==> apply to a memory object
/// ## Very important note
/// The calling application must cast the returned object to
/// the final type, e.g.
/// auto objPtr = (MyClass*)directory->GetObject("some object of MyClass");
virtual Int_t GetBufferSize() const;
/// Return the buffer size to create new TKeys.
/// If the stored fBufferSize is null, the value returned is the average
/// buffer size of objects in the file so far.
const TDatime &GetCreationDate() const { return fDatimeC; }
virtual TFile *GetFile() const { return fFile; }
virtual TKey *GetKey(const char *name, Short_t cycle=9999) const;
/// Return pointer to key with name,cycle
/// if cycle = 9999 returns highest cycle
virtual TList *GetListOfKeys() const { return fKeys; }
const TDatime &GetModificationDate() const { return fDatimeM; }
virtual Int_t GetNbytesKeys() const { return fNbytesKeys; }
virtual Int_t GetNkeys() const { return fKeys->GetSize(); }
virtual Long64_t GetSeekDir() const { return fSeekDir; }
virtual Long64_t GetSeekParent() const { return fSeekParent; }
virtual Long64_t GetSeekKeys() const { return fSeekKeys; }
Bool_t IsModified() const { return fModified; }
Bool_t IsWritable() const { return fWritable; }
virtual void ls(Option_t *option="") const;
/// List Directory contents
/// Indentation is used to identify the directory tree
/// Subdirectories are listed first, then objects in memory, then objects on the file
/// The option can has the following format: <b>[-d |-m][<regexp>]</b>
/// Options:
/// - -d: only list objects in the file
/// - -m: only list objects in memory
/// The <regexp> will be used to match the name of the objects.
/// By default memory and disk objects are listed.
virtual TDirectory *mkdir(const char *name, const char *title="");
/// Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
/// Returns 0 in case of error or if a sub-directory (hierarchy) with the requested
/// name already exists.
/// Returns a pointer to the created sub-directory or to the top sub-directory of
/// the hierarchy (in the above example, the returned TDirectory * always points
/// to "a").
virtual TFile *OpenFile(const char *name, Option_t *option= "",
const char *ftitle = "", Int_t compress = 1,
Int_t netopt = 0);/// Interface to TFile::Open
virtual void Purge(Short_t nkeep=1);
/// Purge lowest key cycles in a directory.
/// By default, only the highest cycle of a key is kept. Keys for which
/// the "KEEP" flag has been set are not removed. See TKey::Keep().
virtual void ReadAll(Option_t *option="");
/// Read objects from a ROOT file directory into memory.
/// If an object is already in memory, the memory copy is deleted
/// and the object is again read from the file.
/// If opt=="dirs", only subdirectories will be read
/// If opt=="dirs*" complete directory tree will be read
virtual Int_t ReadKeys(Bool_t forceRead=kTRUE);
/// Read the linked list of keys.
/// Every directory has a linked list (fKeys). This linked list has been
/// written on the file via WriteKeys as a single data record.
/// It is interesting to call this function in the following situation.
/// Assume another process1 is connecting this directory in Update mode
/// - Process1 is adding/updating objects in this directory
/// - You want to see the latest status from process1.
/// Example Process1:
/// ~~~{.cpp}
/// obj1.Write();
/// obj2.Write();
/// gDirectory->SaveSelf();
/// ~~~
/// Example Process2:
/// ~~~{.cpp}
/// gDirectory->ReadKeys();
/// obj1->Draw();
/// ~~~
/// This is an efficient way (without opening/closing files) to view
/// the latest updates of a file being modified by another process
/// as it is typically the case in a data acquisition system.
virtual Int_t ReadTObject(TObject *obj, const char *keyname);
/// Read object with keyname from the current directory
/// Read contents of object with specified name from the current directory.
/// First the key with keyname is searched in the current directory,
/// next the key buffer is deserialized into the object.
/// The object must have been created before via the default constructor.
/// See TObject::Write().
virtual void ResetAfterMerge(TFileMergeInfo *);
/// Reset the TDirectory after its content has been merged into another
/// Directory.
/// This returns the TDirectoryFile object back to its state
/// before any data has been written to the file.
/// The object in the in-memory list are assumed to also have been reset.
virtual void rmdir(const char *name);
/// Removes subdirectory from the directory
/// When diredctory is deleted, all keys in all subdirectories will be
/// read first and deleted from file (if exists)
/// Equivalent call is Delete("name;*");
virtual void Save();/// Save recursively all directory keys and headers
virtual void SaveSelf(Bool_t force = kFALSE);
/// Save Directory keys and header
/// If the directory has been modified (fModified set), write the keys
/// and the directory header. This function assumes the cd is correctly set.
/// It is recommended to use this function in the following situation:
/// Assume a process1 using a directory in Update mode
/// - New objects or modified objects have been written to the directory.
/// - You do not want to close the file.
/// - You want your changes be visible from another process2 already connected
/// to this directory in read mode.
/// - Call this function.
/// - In process2, use TDirectoryFile::ReadKeys to refresh the directory.
virtual Int_t SaveObjectAs(const TObject *obj, const char *filename="", Option_t *option="") const;
/// Save object in filename.
/// If filename is 0 or "", a file with "objectname.root" is created.
/// The name of the key is the object name.
/// If the operation is successful, it returns the number of bytes written to the file
/// otherwise it returns 0.
/// By default a message is printed. Use option "q" to not print the message.
/// If filename contains ".json" extension, JSON representation of the object
/// will be created and saved in the text file. Such file can be used in
/// JavaScript ROOT (https://root.cern.ch/js/) to display object in web browser
/// When creating JSON file, option string may contain compression level from 0 to 3 (default 0)
virtual void SetBufferSize(Int_t bufsize);
/// Set the default buffer size when creating new TKeys.
/// See also TDirectoryFile::GetBufferSize
void SetModified() {fModified = kTRUE;}
void SetSeekDir(Long64_t v) { fSeekDir = v; }
virtual void SetTRefAction(TObject *ref, TObject *parent);
/// Find the action to be executed in the dictionary of the parent class
/// and store the corresponding exec number into fBits.
/// This function searches a data member in the class of parent with an
/// offset corresponding to this.
/// If a comment "TEXEC:" is found in the comment field of the data member,
/// the function stores the exec identifier of the exec statement
/// following this keyword.
void SetWritable(Bool_t writable=kTRUE);
/// Set the new value of fWritable recursively
virtual Int_t Sizeof() const;
/// Return the size in bytes of the directory header
virtual Int_t Write(const char *name=0, Int_t opt=0, Int_t bufsize=0);
/// Write all objects in memory to disk.
/// Loop on all objects in memory (including subdirectories).
/// A new key is created in the keys linked list for each object.
/// For allowed options see TObject::Write().
/// The directory header info is rewritten on the directory header record.
virtual Int_t Write(const char *name=0, Int_t opt=0, Int_t bufsize=0) const ;
/// One can not save a const TDirectory object.
virtual Int_t WriteTObject(const TObject *obj, const char *name=0, Option_t *option="", Int_t bufsize=0);
/// Write object obj to this directory.
/// The data structure corresponding to this object is serialized.
/// The corresponding buffer is written to this directory
/// with an associated key with name "name".
/// Writing an object to a file involves the following steps:
/// - Creation of a support TKey object in the directory. The TKey object
/// creates a TBuffer object.
/// - The TBuffer object is filled via the class::Streamer function.
/// - If the file is compressed (default) a second buffer is created to hold
/// the compressed buffer.
/// - Reservation of the corresponding space in the file by looking in the
/// TFree list of free blocks of the file.
/// - The buffer is written to the file.
/// By default, the buffersize will be taken from the average buffer size
/// of all objects written to the current file so far.
/// Use TDirectoryFile::SetBufferSize to force a given buffer size.
/// If a name is specified, it will be the name of the key.
/// If name is not given, the name of the key will be the name as returned
/// by obj->GetName().
/// The option can be a combination of:
/// - "SingleKey"
/// - "Overwrite"
/// - "WriteDelete"
/// Using the "Overwrite" option a previous key with the same name is
/// overwritten. The previous key is deleted before writing the new object.
/// Using the "WriteDelete" option a previous key with the same name is
/// deleted only after the new object has been written. This option
/// is safer than kOverwrite but it is slower.
/// The "SingleKey" option is only used by TCollection::Write() to write
/// a container with a single key instead of each object in the container
/// with its own key.
/// An object is read from this directory via TDirectoryFile::Get.
/// The function returns the total number of bytes written to the directory.
/// It returns 0 if the object cannot be written.
/// WARNING: avoid special characters like '^','$','.' in the name as they
/// are used by the regular expression parser (see TRegexp).
virtual Int_t WriteObjectAny(const void *obj, const char *classname, const char *name, Option_t *option="", Int_t bufsize=0);
/// Write object from pointer of class classname in this directory.
/// obj may not derive from TObject. See TDirectoryFile::WriteTObject for comments
/// ## Very important note
/// The value passed as 'obj' needs to be from a pointer to the type described by classname.
/// For example:
/// ~~~{.cpp}
/// TopClass *top;
/// BottomClass *bottom;
/// top = bottom;
/// ~~~
/// you can do:
/// ~~~{.cpp}
/// directory->WriteObjectAny(top,"top","name of object");
/// directory->WriteObjectAny(bottom,"bottom","name of object");
/// ~~~
/// <b>BUT YOU CAN NOT DO</b> the following since it will fail with multiple inheritance:
/// ~~~{.cpp}
/// directory->WriteObjectAny(top,"bottom","name of object");
/// ~~~
/// We <b>STRONGLY</b> recommend to use
/// ~~~{.cpp}
/// TopClass *top = ....;
/// directory->WriteObject(top,"name of object")
/// ~~~
/// See also remarks in TDirectoryFile::WriteTObject
virtual Int_t WriteObjectAny(const void *obj, const TClass *cl, const char *name, Option_t *option="", Int_t bufsize=0);
/// Write object of class with dictionary cl in this directory.
/// obj may not derive from TObject
/// To get the TClass* cl pointer, one can use
/// TClass *cl = TClass::GetClass("classname");
/// An alternative is to call the function WriteObjectAny above.
/// see TDirectoryFile::WriteTObject for comments
virtual void WriteDirHeader();/// Overwrite the Directory header record.
virtual void WriteKeys();
/// Write Keys linked list on the file.
/// The linked list of keys (fKeys) is written as a single data record