On Fri, 4 Dec 1998, Rene Brun wrote: > Your code below will work only for simple cases. It also implies > that your objects must be in memory first. > The development of a true Cp and Mv functions is more work. > Copying/Moving should not require the import in memory with object > expansion. A simple transfert of the stream of bytes is required. > The difficulty is to support trees in this mode. Hello, I have a revised version of my code on roottalk which will correctly handle TH1 derivatives and TDirectories in memory. Of course you are right that requirering things to be in memory is a limitation. For general interest, here is the code. ... bool RooTupleManager::setFileName( const char* file ) { // Make sure we are at the top of the current file, then save: checkFile(); rtfilep->cd(); write(); // Create the new file and transfer all objects from existing to new // file. Function movedir will call itself recursively for directories. TFile* filep= new TFile( file, "RECREATE", "Created for you again by RooTupleManager" ); movedir( rtfilep, filep ); // Now we can safely get rid of the old file: delete rtfilep; rtfilep= filep; // The End: return true; } // Recursively move contents of olddir to newdir: void RooTupleManager::movedir( TDirectory* olddir, TDirectory* newdir ) { TList* list1= olddir->GetList(); TIter iter( list1 ); TObject* obj= 0; while( obj= iter.Next() ) { if( obj->InheritsFrom( "TH1" ) ) { // TH1::SetDirectory does all the work for us: ((TH1*)obj)->SetDirectory( newdir ); } else if( strcmp( obj->ClassName(), "TDirectory" ) == 0 ) { // Have to do it by hand recursively for TDirectory: list1->Remove( obj ); TDirectory* dir= newdir->mkdir( obj->GetName() ); movedir( (TDirectory*)obj, dir ); } } return; } ... I have to create new TDirectories when I move their contents, because they know about their file and this can't be changed. It would perhaps be better, if TDirectory would not hold a pointer to the file, but would rather ask its "mother" for the file pointer. You could have (public) member functions TFile* TDirectory::GetFile() { return fmother->GetFile(); } and TFile* Tfile::GetFile() { return this; } So, when you need to the know the file a TDirectory is attached to the call will cascade up the directory tree until you hit the current TFile. If you move a TDirectory to another directory tree rooted in a different file everything will be ok. Objects (entries) in a TDirectory should not hold their own file pointers, but should rather call fDirectory->GetFile(). In this way you could move a whole TDirectory and everything below it in one go. Just a thought, cheers, Stefan ---Stefan Kluth---------------Lynen Fellow----------------|\--|\------- - LBNL, MS 50A 2160 - phone: +1 510 495 2376 - |/ |/ - - 1 Cyclotron Rd. - fax: +1 510 495 2957 - |\/\|\/\|' - ---Berkeley, CA94720, USA-----e-mail: SKluth@lbl.gov------|/\/|/\/|----
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:40 MET