2010-12-13 25 views
9

मैं एक तृतीय पक्ष लाइब्रेरी का उपयोग कर रहा हूं जो मूल रूप से विभिन्न प्रकार की फाइलों और उपनिर्देशिकाओं के साथ एक आउटपुट निर्देशिका बनाता है। मैं यह पुष्टि करने के लिए यूनिट परीक्षण लिखने में सक्षम होना चाहता हूं कि आउटपुट सही है।java.io. * एपीआई के साथ उपयोग करने के लिए जावा रैम डिस्क बनाया जा सकता है?

मैं रैम डिस्क के साथ lib का उपयोग करने में सक्षम होना चाहता हूं, ताकि लाइब्रेरी कुछ भी वास्तविक डिस्क प्लेटों को किसी भी तरह से छूने में सक्षम न हो। विचार है कि परीक्षण चलाने और साफ करने के लिए परीक्षण करना बहुत मुश्किल है (रैम डिस्क ड्रॉप करें?)।

मेरे लिए उपलब्ध दो सबसे प्रमुख विकल्प Commons VFS और JSR 203 हैं। पूर्व मेरे लिए कोई उपयोग नहीं है क्योंकि मैं java.io. * एपीआई और कॉमन्स वीएफएस कक्षाओं का उपयोग करके चीजों को पारदर्शी रूप से काम करना चाहता हूं। बाद में इसे काट नहीं है क्योंकि मुझे जेडीके 6 के साथ करना है (यह जेडीके 7 का हिस्सा माना जाता है) और मुझे नहीं पता कि यह java.io. * के साथ सहजता से काम करेगा या नहीं (मैं नहीं चाहता इस पर शर्त लगा लो)।

other समाधान भी हैं, लेकिन मैं उन कारणों का उपयोग नहीं कर सकता क्योंकि मैं कॉमन्स वीएफएस का उपयोग नहीं कर सकता। प्रश्न में लाइब्रेरी की जटिलता के कारण मॉक्स सवाल से बाहर हैं।

मेरी लिनक्स मशीन पर, मैं आसानी से एक रैम ड्राइव बना सकता हूं और java.io. * एपीआई का उपयोग उसी तरह करता हूं जैसे मैं डिस्क पर फ़ाइलों के साथ करता हूं। बात यह है कि, मैं चाहता हूं कि यह क्रॉस-प्लेटफ़ॉर्म और अधिक विशेष रूप से डिस्क को बाहरी प्रक्रिया के बजाय परीक्षण प्रक्रिया का एक हिस्सा बनाने के लिए तैयार करे।

तो, क्या जावा में रैम ड्राइव पंजीकृत करने का कोई तरीका है जो मानक java.io. * एपीआई के साथ प्रयोग योग्य होगा?

+3

जावा के बाहर क्यों नहीं दिखता है। ओएस स्तर पर एक रैम डिस्क बनाएं (उपकरण विन्डोज़ और लिनक्स के लिए मौजूद हैं) और बस अपनी लाइब्रेरी को पथ के रूप में दें। –

+4

मैंने पहले ही समझाया है क्यों: मैं आदर्श रूप से प्रक्रिया को मंच-स्वतंत्र होना चाहता था। इसके अतिरिक्त, मैं एक पर्यावरण या किसी अन्य में रैम डिस्क को सेट अप और निपटाने के लिए बाहरी स्क्रिप्ट लिखने के बजाय, जावा में होने के लिए आवश्यक आवश्यक कोड पसंद करूंगा। –

+0

क्या आपको कोई समाधान मिला है? जावा 7 या जावा 8 के लिए। – Jus12

उत्तर

6

तो, क्या जावा में रैम ड्राइव पंजीकृत करने का कोई तरीका है जो मानक java.io. * एपीआई के साथ प्रयोग योग्य होगा?

जावा 6 या पहले JVM के साथ नहीं। जावा 6 और इससे पहले फाइल सिस्टम या फाइल सिस्टम प्रकारों को पंजीकृत करने के लिए कोई एसपीआई प्रदान नहीं करते हैं। इसलिए, एक रैम एफएस को लागू करने के लिए कि एक सामान्य एफएस की तरह एक आवेदन का उपयोग करेगा java.io.* कक्षाओं के व्यवहार को संशोधित करने में संलग्न होगा।

मुझे लगता है कि आप जो कर सकते हैं सबसे अच्छी बात मेजबान ऑपरेटिंग सिस्टम द्वारा लागू रैम एफएस का उपयोग करना होगा। आप जावा से उस तक पहुंचने में सक्षम होना चाहिए जैसे कि यह एक सामान्य फाइल सिस्टम था। हालांकि, I/O सिस्टम कॉल को लागू करेगा, इसलिए यह उतना तेज़ नहीं होगा जितना कि RAM फ़ाइल सिस्टम JVM प्रबंधित स्मृति में आयोजित किया गया था।

+0

एक स्पष्ट और सटीक उत्तर के लिए धन्यवाद। जैसा कि यह खड़ा है, मैं शायद परीक्षणों को एकीकरण परीक्षणों और उन लोगों के साथ काम करने के लिए हटा दूंगा। –

4

सैद्धांतिक रूप से स्टीफन सही है। लेकिन मैं आपको एक चाल का सुझाव दे सकता हूं। आप अपने स्वयं के FileInputStream और FileOutputStream को कार्यान्वित कर सकते हैं और उन्हें bootclasspath में डाल सकते हैं। आपका कार्यान्वयन उदाहरण के लिए खुले(), पढ़ें() और readBytes() (जो नियमित फ़ाइल इनपुट स्ट्रीम में मूल विधि हैं) लागू करें।

यह आपकी समस्या के लिए शुद्ध जावा समाधान है। इसका नुकसान यह है कि आपको अपने परीक्षणों को JVM के अलग-अलग उदाहरण में चलाने की ज़रूरत है।

+2

यह वास्तव में "शुद्ध जावा" नहीं है क्योंकि संशोधित सिस्टम कक्षाएं जावा चश्मे के दायरे में नहीं हैं, यानी यह कुछ जावा कार्यान्वयन पर काम कर सकती है, लेकिन दूसरों पर काम नहीं करेगी। –

+2

मेरी समझ यह है कि वह ऐसा नहीं कर सकता है, भले ही वह चाहे। वह कहता है * "[टी] वह बाद में इसे काट नहीं देता क्योंकि मुझे जेडीके 6" * के साथ करना है। यदि वह कस्टम संस्करणों के साथ 'java.io. * 'कक्षाओं को प्रतिस्थापित करता है तो यह अब जावा 6 नहीं है। (वास्तव में, तकनीकी रूप से यह जावा बिल्कुल नहीं है!) –

+2

इसके अलावा, मानक जावा कक्षाओं को प्रतिस्थापित करना निश्चित रूप से "शुद्ध जावा" नहीं है; यह लिंक देखें - http://www.javacoffeebreak.com/faq/faq0006.html। एक हैक किए गए JVM के आधार पर स्वचालित रूप से आपके कोड को गैर पोर्टेबल प्रस्तुत करता है, और इसलिए "शुद्ध जावा", आईएमओ नहीं। –

1

मूल समस्या जिसे आप दूर करने की मांग कर रहे हैं वह यह है कि मूल java.io एपीआई बिल्कुल लचीले नहीं हैं (वे सभी कंक्रीट कक्षाओं को संदर्भित करते हैं)। एकमात्र तरीका है कि आप विभिन्न कार्यक्षमता डाल सकते हैं, उदाहरण के लिए java.io.File, बेस क्लास को विस्तारित करके है।

डिज़ाइन किए जाने के बाद कक्षाओं को विस्तारित करना खराब डिज़ाइन हो सकता है (बस Properties कक्षा को देखें) - यही कारण है कि आपको शायद ऐसा कोई लाइब्रेरी नहीं मिलेगी जो ऐसा करता है।

कुछ भी आपको java.io.File कक्षा को विस्तारित करने से रोकता है, और सभी विधियों को प्रॉक्सी करता है, उदाहरण के लिए, कॉमन्स वीएफएस एपीआई के FileObject

संपादित: हालांकि, वहाँ चीजें हैं जो शायद उस दृष्टिकोण के तहत असफल हो जायेगी कर रहे हैं - उदाहरण के लिए, File कंस्ट्रक्टर्स कि एक माता पिता File लेने का उपयोग कर।

संपादित 2:

public class VirtualFile extends java.io.File { 
    public static VirtualFile fromFile(File file) { 
     if (file instanceof VirtualFile) { 
      return (VirtualFile) file; 
     } else { 
      FileSystemManager fsm = new DefaultFileSystemManager(); 
      return fsm.toFileObject(file); 
     } 
    } 

    private final org.apache.commons.vfs.FileObject mProxyFileObject; 


    public VirtualFile(FileObject proxy) { 
     super("/tmp/xxxx"); // That part needs some work to be cross-platform. 
          // However, such a construction will completely 
          // destroy the expectations that other classes 
          // have about what a File is. 
     mProxyFileObject = proxy; 
    } 

    public VirtualFile(VirtualFile parent, String child) { 
     this(parent.mProxyFileObject.resolveFile(child)); 
    } 

    public VirtualFile(File parent, String child) { 
     this(fromFile(parent), child); 
    } 

    @Override 
    public boolean canExecute() { 
     throw new UnsupportedOperationException(); 
    } 

    @Override 
    public boolean canRead() { 
     try { 
      return mProxyFileObject.isReadable(); 
     } catch (FileSystemException fse) { 
      // FileSystemException is not a Runtime Exception :(
      throw new RuntimeException(fse); 
     } 
    } 

    // Override ALL public methods to throw Exceptions; 
    // implement or mock only the methods that you need. 
} 

क्यों File(File, String) निर्माता कि सेटअप के साथ काम नहीं करेंगे के रूप में: कि निर्माता File के एक कार्यान्वयन निकलने की आशा नहीं करता है ठीक है, मैं ऐसा ही कुछ के साथ शुरू होगा कक्षा का अनुबंध - जब हम super("/tmp/xxxx") पर कॉल करते हैं तो हम करते हैं। (और हम वर्ग के अनुबंध को तोड़ने से नहीं बच सकते हैं, क्योंकि जिन वर्चुअल फाइलों के साथ हम काम करना चाहते हैं, उनके पास सादा File समतुल्य नहीं है)

तो, आप हैं - इसे काम का एक मामूली काम की आवश्यकता होगी, और एक महत्वपूर्ण मौका है कि लाइब्रेरी वैसे भी काम नहीं करेगा।

+0

क्या आप java.io.File से प्रॉक्सी कॉल करने के बारे में कुछ बता सकते हैं उदा। एक फ़ाइल ऑब्जेक्ट और फ़ाइल (फ़ाइल) कन्स्ट्रक्टर के साथ क्या समस्या होगी? –

+0

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

+0

@ टॉमिस्लाव: मुझे नहीं पता था कि लाइब्रेरी पर आपके पास कितना नियंत्रण था - या शायद आप पुस्तकालय में मूल 'फ़ाइल' प्रदान करने में सक्षम होंगे। –