2012-12-12 2 views
8

में एचडीएफ 5 फाइलों को खोलने का बेहतर तरीका मैं एचडीएफ 5 सी ++ बाइंडिंग की कुछ कमियों को पाने के लिए एक तरीके से आने का प्रयास कर रहा हूं। - सभी मैं करना चाहता हूँ पढ़ने/लिखने के लिए एक्सेस के लिए एक फ़ाइल खोलने के लिए है, और अगर यह नहीं करता हैसी ++

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); 
} 

यह आवश्यक नहीं होना चाहिए: वर्तमान में, मेरी कोड निम्न के समान ट्राई/कैच ब्लॉक से अटे पड़े है इसे बनाने के लिए मौजूद नहीं है। एक और, कठिन समस्या है नेस्टेड समूह (जैसे "/ parent/group") बनाना, जहां मूल समूह आवश्यक रूप से मौजूद नहीं है। यूनिक्स/लिनक्स में, बराबर

mkdir -p parent/group 

हालांकि, HDF5 सी ++ बाइंडिंग में हो सकता है, एक समूह जिसकी मूल समूह मौजूद नहीं है एक अपवाद को जन्म देती है निर्माण।

इन कारणों से, मुझे एक हेडर फ़ाइल बनाने के लिए प्रेरित किया गया है जो इन सामान्य समस्याओं में से कुछ से संबंधित है। मेरा पहला विचार केवल कार्यों का एक सेट बनाना था, उदाहरण के लिए, एक फ़ाइल नाम और एक्सेस मोड लें और एक H5 :: H5File ऑब्जेक्ट वापस करें, या समूह का नाम लें और समूह ऑब्जेक्ट को वापस करें। मुझे लगता है कि यह आदर्श से कम है, हालांकि, यह प्रोग्रामर को छोड़ देता है जो लौटे ऑब्जेक्ट्स पर "डिलीट" कॉल करने के लिए इस हेडर फ़ाइल का उपयोग करता है, भले ही प्रोग्रामर कभी भी अपने कोड में "नया" नहीं कहता। ऐसा लगता है कि स्मृति रिसाव के लिए पूछ रहा है।

मेरा दूसरा विचार एच 5 :: एच 5फाइल और एच 5 :: एच 5 ग्रुप से व्युत्पन्न कक्षाओं का एक सेट बनाना था, जो रचनाकारों के साथ है जो फ़ाइल अभी तक मौजूद नहीं है, या जब समूह के मूल समूह अभी तक मौजूद नहीं है

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() { } 

समस्या यह है कि मैं में चल रहा दोहरा है: ली गई फ़ाइल वर्ग के लिए मेरे प्रयास इस प्रकार थी। सबसे पहले, निर्माता में आज़माएं/कैच ब्लॉक

H5::H5File(fname.c_str(), H5F_ACC_RDWR) 

जब फ़ाइल मौजूद नहीं है के द्वारा बनाई गई अपवाद फिर से फेंकता है, तो कार्यक्रम अभी भी समाप्त हो जाता है। दूसरी समस्या यह है कि मुझे लगता है कि दूसरा निर्माता यकीन नहीं है

H5::H5File(fname.c_str(), H5F_ACC_TRUNC); 

सही है (यानी यह माता पिता के वर्ग का निर्माण करता है?) वहाँ आधार वर्ग 'निर्माता में व्युत्पन्न वर्ग पकड़ अपवाद के लिए एक रास्ता है , और फिर बेस क्लास के लिए एक अलग कन्स्ट्रक्टर कॉल करें?

अधिक आम तौर पर, क्या कोई भी एचडीएफ 5 सी ++ बाइंडिंग की इन कमियों से निपटने के बेहतर/अधिक सुरुचिपूर्ण तरीके के बारे में सोच सकता है?

+0

"(/ माता-पिता/समूह", जहां मूल समूह जरूरी मौजूद नहीं है यूनिक्स/लिनक्स में, बराबर होगा एक और, जटिल समस्या एक नेस्टेड समूह जैसे) बनाने के लिए है ".. "- क्या आपको कभी ऐसा करने का अच्छा तरीका मिला? –

+2

यदि आपको "/ parent/group/subgroup" जैसे नेस्टेड समूह का नाम दिया गया है, तो पहले इसे "/ parent", "/ parent/group", और "/ parent/group/subgroup" में विभाजित करें, और उसके बाद क्रम में प्रत्येक को खोलने की कोशिश करें। यदि कोई दिया गया समूह मौजूद नहीं है (सी ++ एपीआई में, आपको एक 'एच 5 :: फाइलआईएक्सप्शन' मिलेगा), इसे बनाएं। मैंने लिखा [कुछ सहायक कार्य जो इस समस्या से निपटते हैं] (https://github.com/gregreen/h5utils/blob/master/src/h5utils.cpp#L92)। – Thucydides411

+0

हाल ही में एक ही समस्या थी http://stackoverflow.com/questions/35668056/test-group-existence-in-hdf5-c। कोई हल नहीं। उस के शीर्ष पर, मैंने अभी ध्यान दिया है कि एच 5 :: अपवाद std :: अपवाद से प्राप्त नहीं होता है ...? – eudoxos

उत्तर

8

मैं कुछ सरल सहायक कार्यों को बनाने का आपका प्रारंभिक विचार पसंद करता हूं - यह आपके लिए लिखने और दस्तावेज़ के लिए आवश्यक कोड की मात्रा को सरल और कम करेगा। इसके अतिरिक्त, उचित मेमोरी प्रबंधन सुनिश्चित करने के लिए, आप shared_ptr का उपयोग कर सकते हैं। HDF5 सी ++ बाइंडिंग में

// a typedef for our managed H5File pointer 
typedef std::shared_ptr<H5::H5File> H5FilePtr; 

// create or open a file 
H5FilePtr create_or_open(const std::string& fname) 
{ 
    H5::Exception::dontPrint(); 
    H5::H5File* file = 0; 

    try { 
     file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR); 
    } catch(const H5::FileIException&) { 
     file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC); 
    } 

    return H5FilePtr(file); 
} 
3

हालांकि, एक समूह जिसकी मूल समूह मौजूद नहीं है एक अपवाद को जन्म देती है बनाने:

यहाँ अपने प्रारंभिक उदाहरण के लिए एक सरल आवरण समारोह बराबर है।

आप लिंक निर्माण संपत्ति सूची को create missing intermediate groups पर सेट कर सकते हैं, और इस अपवाद से बचें।उदाहरण के लिए:।

#include "hdf5.h" 

int main (void){ 
    hid_t lcpl, file_id, group_id; 
    herr_t status; 
    unsigned flag=1; 

    lcpl = H5Pcreate(H5P_LINK_CREATE); 
    status = H5Pset_create_intermediate_group(lcpl, flag); 
    file_id = H5Fcreate("nested_groups.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 
    group_id = H5Gcreate(file_id, "/foo/bar/bop", lcpl, H5P_DEFAULT, H5P_DEFAULT); 

    H5Pclose(lcpl); 
    H5Gclose(group_id); 
    H5Fclose(file_id); 

    return status; 
} 
+0

सी ++ में लिखते समय भी सी एपीआई का उपयोग करने के लिए यह एक और तर्क है। ऑब्जेक्ट-ओरिएंटेड सी ++ एपीआई में बहुत सारी कार्यक्षमता गायब है, और कुछ डिज़ाइन विकल्प, जैसे फ़्लैग सेट करने के बजाय अपवाद फेंकना, काफी परेशान हैं। – Thucydides411