Hi Rene, Thanks for the fix and I have tested it and find that it works. I'd like to request one more change please to accomodate another use case for this particular situation in which the file has been opened by the writer but no keys have been written to the file. This additional use case is that we have a daq -> dispatcher configuration running at our detector site in which a dispatcher serves data from the data file while the daq is still writing to it. To support this, the daq writer uses TDirectory::SaveSelf, and the dispatcher reader uses TDirectory::ReadKeys as is described under TDirectory::ReadKeys. This works well as long as at least 1 key has been written to the file by the daq writer. In the case described below, in which the file has been opened by the writer, but no key has yet been written to the file, I would like to be able to open the file with no error message reported, and have TDirectory::ReadKeys return the number of keys = 0. This would allow me to treat this particular case the same as if one or more keys have been written to the file. I have played with implementing this in my own TFile.cxx and TDirectory.cxx and have attached what I have done. It works for my tests, although I am sure I have not done implemented it carefully enough. It is just to give you an idea of the behavior I'm hoping for. -Sue In TFile::Init change: //*-* -------------Read keys of the top directory if (fSeekKeys > fBEGIN && fEND <= size) { TDirectory::ReadKeys(); gDirectory = this; } else { if (fEND > size) { Error("TFile","file %s is truncated at %d bytes: should be %d, tryi\ng to recover",GetName(),size,fEND); } else { Warning("TFile","file %s probably not closed, trying to recover",Ge\tName()); } if (!Recover()) goto zombie; } to: //*-* -------------Read keys of the top directory if ( fEND <= size) { TDirectory::ReadKeys(); gDirectory = this; } else { Error("TFile","file %s is truncated at %d bytes: should be %d, tryi\ng to recover",GetName(),size,fEND); if (!Recover()) goto zombie; } In TDirectory::ReadKeys change: TKey *headerkey = new TKey(fSeekKeys,fNbytesKeys); headerkey->ReadFile(); buffer = headerkey->GetBuffer(); headerkey->ReadBuffer(buffer); Int_t nkeys; TKey *key; frombuf(buffer, &nkeys); for (Int_t i = 0; i < nkeys; i++) { key = new TKey(); key->ReadBuffer(buffer); fKeys->Add(key); } delete headerkey; to: Int_t nkeys = 0; if ( fSeekKeys > 0) { TKey *headerkey = new TKey(fSeekKeys,fNbytesKeys); headerkey->ReadFile(); buffer = headerkey->GetBuffer(); headerkey->ReadBuffer(buffer); TKey *key; frombuf(buffer, &nkeys); for (Int_t i = 0; i < nkeys; i++) { key = new TKey(); key->ReadBuffer(buffer); fKeys->Add(key); } delete headerkey; } Rene Brun wrote: > Hi Sue, > > I have modified TFile::Recover such that the file is declared a Zombie > if no keys can be recovered. Fix in CVS. > > Rene Brun > > Susan Kasahara wrote: > > > > Hi root team, > > Sometimes we need to read a file that was left open by an aborted write job. In this > > case the file is not properly closed, and on read of the file the TFile::Recover method > > will attempt to rebuild the key directory for the file. If the TFile::Recover method > > fails to recover any keys for the file it prints the warning message: "no keys recovered" > > for the file, but I can't seem to find a way to determine at run time that in this case the > > file is unreadable. The TFile methods IsZombie() and IsOpen() both indicate after > > TFile construction that the file is open and ready to be read. This causes my code > > to go ahead and attempt to read the set of keys from the file (TDirectory::ReadKeys > > returns a non-null number of keys) and use the keys, eventually resulting in a segv. > > Is it possible to determine at run-time that the file was not recoverable? > > I am using cvs root last updated on 1/22/02. > > -Sue
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:41 MET