Ho cercato di trovare un modo per aggirare alcuni dei limiti delle associazioni C++ HDF5. Attualmente, il mio codice è disseminato di blocchi try/catch simili a quanto segue:Un modo migliore per aprire i file HDF5 in C++
H5::Exception::dontPrint();
H5::H5File *file = NULL;
try {
file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR);
} catch(H5::FileIException &file_exists_err) {
file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}
Questo non dovrebbe essere necessario - tutto quello che voglio fare è quello di aprire un file per l'accesso in lettura/scrittura, e se doesn esiste, per crearlo. Un altro problema più complesso consiste nel creare un gruppo nidificato (ad esempio "/ parent/gruppo"), in cui il gruppo principale non esiste necessariamente. In Unix/Linux, l'equivalente sarebbe
mkdir -p parent/group
Tuttavia, nel HDF5 C++ attacchi, la creazione di un gruppo il cui gruppo principale non esiste solleva un'eccezione.
Per questi motivi, sono stato motivato a creare un file di intestazione che tratta alcuni di questi problemi comuni. Il mio primo pensiero è stato semplicemente creare un insieme di funzioni che, ad esempio, prendessero un nome di file e una modalità di accesso e restituissero un oggetto H5 :: H5File, o prendessero un nome di gruppo e restituissero un oggetto di gruppo. Penso che questo sia tutt'altro che ideale, tuttavia, poiché lascia il programmatore che usa questo file di intestazione per chiamare "delete" sugli oggetti restituiti, anche se il programmatore non chiama esplicitamente "nuovo" nel proprio codice. Questo sembra chiedere perdite di memoria.
Il mio secondo pensiero, quindi, era di creare un set di classi derivate da H5 :: H5File e H5 :: H5Group, con costruttori che non generano eccezioni quando il file non esiste ancora o quando il gruppo principale del gruppo non esiste ancora. Il mio tentativo per la classe di file derivato è stato il seguente:
namespace H5Utils {
class H5File : public H5::H5File {
public:
H5File(std::string fname);
~H5File();
};
}
H5Utils::H5File::H5File(std::string fname)
try : H5::H5File(fname.c_str(), H5F_ACC_RDWR)
{
std::cerr << "Opened existing file." << std::endl;
} catch(H5::FileIException &file_exists_err) {
std::cerr << "File does not exist. Creating new file." << std::endl;
H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}
H5Utils::H5File::~H5File() { }
Il problema che sto funzionando in è duplice. In primo luogo, il blocco try/catch nel costruttore ri-genera l'eccezione creato da
H5::H5File(fname.c_str(), H5F_ACC_RDWR)
quando il file non esiste, in modo da programma termina ancora. Il secondo problema è che io non sono sicuro che il secondo costruttore,
H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
è corretto (cioè vuol costruire la classe genitore?) C'è un modo per avere i derivati eccezioni classe di cattura nel costruttore della classe base e quindi chiamare un costruttore diverso per la classe base?
Più in generale, qualcuno può pensare a un modo migliore/più elegante di gestire questi limiti delle associazioni HDF5 C++?
"Un altro, problema più complicato è quello di creare un gruppo nidificato (ad esempio '/ genitore/gruppo'), dove il gruppo padre non necessariamente esiste In Unix/Linux, l'equivalente sarebbe ... . "- Hai mai trovato un bel modo per farlo? –
Se viene assegnato un nome di gruppo nidificato, ad esempio "/ parent/group/subgroup", dividerlo in "/ parent", "/ parent/group" e "/ parent/group/subgroup", quindi prova ad aprire ognuno in ordine. Se un determinato gruppo non esiste (nell'API C++, otterresti un 'H5 :: FileIException'), crealo. Ho scritto [alcune funzioni di supporto che trattano questo problema] (https://github.com/gregreen/h5utils/blob/master/src/h5utils.cpp#L92). – Thucydides411
Aveva lo stesso problema recentemente http://stackoverflow.com/questions/35668056/test-group-existence-in-hdf5-c. Nessuna soluzione. In cima a ciò, ho appena notato che H5 :: Exception non deriva da std :: exception ...? – eudoxos