क्या जावा के लिए कोई फेक फाइल सिस्टम फ्रेमवर्क हैं? [बन्द है]


83

मैं एक ऐसी परियोजना में परीक्षण शुरू कर रहा हूं जो आईओ संचालन (फाइल सिस्टम, इस मामले में) का भारी उपयोग करता है। सिस्टम लगातार फाइलों को खोलता / बंद करता है, जाँचता है कि क्या फाइलें मौजूद हैं, उन्हें हटा देती है, वगैरह।

यह जल्द ही स्पष्ट हो गया कि नियमित रूप से मॉकिंग करने से ज्यादा फायदा नहीं होगा, क्योंकि यह मेरे परीक्षणों को स्थापित करने और इसके बारे में तर्क करने के लिए कठिन होगा। दूसरी ओर, एक नकली फाइल सिस्टम का होना भयानक होगा, और मुझे लगता है, सेट करना बहुत आसान है।

ऐसा लगता है कि माणिक लोगों ने इसे फिर से किया, और ठीक वही है जो मैं रूबी में पूछ रहा हूं: http://ozmm.org/posts/fakefs.html

क्या जावा के लिए दूरस्थ रूप से कुछ समान है?


1
यह एक ऐसा अनुप्रयोग स्तर दिखता है जो स्थिर प्रकार की प्रणाली के बिना भाषाओं में करना आसान होता है। जावा में, एक फ़ाइल / FileInputStream / FileOutputStream हमेशा अंतर्निहित सिस्टम की फाइल सिस्टम को संदर्भित करेगा - यदि आप VM को पैच नहीं करते हैं।
पाओलो एबरमन

JavaFileManager या FileSystemView जैसे इंटरफेस हैं जिन्हें आप लागू कर सकते हैं, लेकिन अधिकांश प्रोग्राम उनका उपयोग नहीं करेंगे।
पाओलो एबरमन

@ पहली टिप्पणी: मैं इससे अच्छी तरह परिचित हूं। मैंने वर्तमान में फ़ाइल के सभी उपयोगों को अपने स्वयं के फ़ाइलनाम में बदल दिया है जिसमें केवल एक स्ट्रिंग के रूप में फ़ाइल का नाम है। सभी IO तर्क IFileSystem इंटरफ़ेस पर केंद्रित थे। मेरे पास जो समस्या है वह यह है कि यह अभी भी नकली फाइल सिस्टम को लागू करने के लिए काम के एक पूरे दिन की तरह होगा, जिस तरह से मुझे इसकी आवश्यकता थी (फाइलों के लिए समर्थन के साथ + छिपी हुई फाइलें + नाम बदला + एक फ़ाइल नाम से केवल पथ प्राप्त करना) + ...) और इसे परीक्षण करना, यह जानने के लिए कि वास्तव में यह सही है।
Elysium

1
चूँकि आपने ओपी में रूबी का उल्लेख किया है, मैं सिर्फ यहाँ जोड़ना चाहूँगा कि C #, System.IO.Abstractions में एक समतुल्य है जो मैंने हाल ही में उपयोग करना शुरू किया है और काफी अच्छा है।
जुलैलेगॉन

जवाबों:


52

Google के पास Java 7 के FileSystemProvider का एक ओपन-सोर्स, इन-मेमोरी कार्यान्वयन है। परियोजना jimfs कहा जाता है


यदि आप जावा 6 या उससे पहले का उपयोग करते हैं, तो एक विकल्प है: मैंने अपाचे कॉमन्स वीएफएस का उपयोग बड़ी सफलता से पहले किया है। ऐसा लगता है कि कस्टम FileSystemProvider की तरह एक और उत्तर देने वाले का उल्लेख जावा 7 में है।

यह कई फाइल-सिस्टम कार्यान्वयन के साथ प्री-लोडेड आता है : फ़ाइल, रैम, एस / एफ़टीपी, और कुछ का नाम रखने के लिए जार। मैंने S3 के लिए एक प्लगइन भी देखा है ।


6
+1 से jimfs, जिसने मुझे एक ही बदलाव के बिना अपने कोड का परीक्षण करने की अनुमति दी। (मैं Pathदुर्घटना से इस्तेमाल किया गया)
user1071136

35

जावा 6 और पूर्व में यह मुश्किल है क्योंकि कक्षाएं पसंद हैं Fileऔर FileInputStreamजावा अंतरिक्ष में विभिन्न "वर्चुअल फाइल सिस्टम" को भेजने का कोई रास्ता नहीं प्रदान करती हैं।

जावा 7 में, वर्चुअल फ़ाइल सिस्टम के लिए समर्थन है; कस्टम फ़ाइल सिस्टम प्रदाता का विकास करना देखें । मैं नहीं जानता कि क्या यह आपको वह करने की अनुमति देगा जो आप करना चाहते हैं, लेकिन यह एक अच्छी जगह है।


भावहीन। इस तथ्य के कारण कि वास्तव में कोई भी नकली फाइल सिस्टम नहीं है, मुझे लगता है कि मैं सिर्फ अपने द्वारा न्यूनतम कार्यान्वयन लागू करूंगा। मैं FileSystemProvider का उपयोग करके कुछ भी नहीं जीता

वास्तव में, आप FileSystemProvider का उपयोग करके जीतते हैं:

  • आप कुछ को लागू करते हैं (यदि एक खुले स्रोत लाइसेंस के तहत जारी किया गया है) आपकी स्थिति में अन्य लोगों के लिए, और अन्य उद्देश्यों के लिए बहुत उपयोगी हो सकता है।

  • यदि आप किसी FileSystemProvider पर स्विच करने का निर्णय लेते हैं तो यह आपके लिए आसान हो जाता है कि कोई और अभी काम कर रहा है।


दिलचस्प है, लेकिन जैसा कि मुझे लगता है कि मुझे अभी भी फ़ाइल सिस्टम को अपने आप से लागू करना होगा, उपयोगी नहीं है?
व्यथित इलिसियम

6
कम से कम यह आपको ऐसा करने की अनुमति देता है। और जैसा कि आपने खुद कहा है - "इसे स्थापित करना आसान होगा"
स्टीफन सी

भावहीन। इस तथ्य के कारण कि वास्तव में कोई भी नकली फाइल सिस्टम नहीं है, मुझे लगता है कि मैं सिर्फ अपने द्वारा न्यूनतम कार्यान्वयन लागू करूंगा। मैं FileSystemProvider का उपयोग करके कुछ भी नहीं जीता।
ईविल्स

@devoured एलीसियम - मेरा अपडेट देखें।
स्टीफन सी

2
+1 लेखन और खुले स्रोत-आईएनजी के समाधान की सिफारिश करने के लिए
विकीनीलियन्स

19

आप JUnit पैकेज org.junit.rules.TemporaryFolderसे उपयोग कर सकते हैं :

TemporaryFolder नियम उन फ़ाइलों और फ़ोल्डरों के निर्माण की अनुमति देता है जिन्हें परीक्षण विधि समाप्त होने पर हटाए जाने की गारंटी दी जाती है (चाहे वह पास हो या विफल हो):

उदाहरण:

final TemporaryFolder testFolder = new TemporaryFolder();
testFolder.create();
final Path filePath = testFolder.newFile("input.txt").toPath();
final Path dirPath = testFolder.newFolder("subfolder").toPath();

वैकल्पिक रूप से .toPath()भाग छोड़ें :

final File filePath = testFolder.newFile("input.txt");

TemporaryFolder मेमोरी में नहीं है।
प्रोगोंपा

8

आप File"API को डेटा लिखने के लिए कहीं और" का उपयोग करके अपने एपीआई को बदलकर , OutputStreamइसके बजाय अपने उत्पादन कोड में Fileएपीआई पास कर FileOutputStreamसकते हैं, लेकिन इसे ByteArrayOutputStreamअपने परीक्षणों से पास कर सकते हैं। A ByteArrayOutputStreamएक इन-मेमोरी स्ट्रीम है, इसलिए यह बहुत तेज़ है और आप बस इसके तरीकों का उपयोग करके इसकी सामग्री का निरीक्षण कर सकते हैं - यह परीक्षण के लिए एकदम सही है। ByteArrayInputStreamयदि आप डेटा पढ़ना चाहते हैं तो भी इसके अनुरूप है ।

फ़ाइल सिस्टम आम तौर पर बहुत तेज़ होते हैं - जब तक आप अपने परीक्षणों में फ़ाइल I / O का एक बड़ा सौदा नहीं कर रहे थे, मैं परेशान नहीं होता।

ध्यान दें कि एक जावा बनाने Fileवस्तु है नहीं डिस्क पर एक फ़ाइल बनाने, यानी निम्न कोड डिस्क में कोई परिवर्तन नहीं करता है:

File f = new File("somepath"); // doesn't create a file on disk

नई फ़ाइल ("कुछ") डिस्क पर एक फ़ाइल नहीं बनाएगी लेकिन यदि आप इसके किसी भी तरीके को चलाने का प्रयास करते हैं तो यह फ़ाइल सिस्टम का उपयोग करेगा। नई फ़ाइल ("xyz") आज़माएं। getAbsolutePath () यह देखने के लिए कि मेरा क्या मतलब है ..
भटके हुए एलिसीम

1
मुझे लगता है कि लोग मान रहे हैं कि मेरी मुख्य चिंता गति है। यह नहीं।
Elysium

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

@devouredelysium new File("xyz").getAbsolutePath()बिल्कुल कुछ भी नहीं जो भी सिवाय करता रास्ता है कि फ़ाइल लौट जाएगा है अगर यह अस्तित्व में। यह फ़ाइल सिस्टम को नहीं बदलता है; यदि फ़ाइल मौजूद नहीं है, तो यह अभी भी पथ के स्ट्रिंग को लौटाता है और फ़ाइल नहीं बनाता है। "देखिए क्या होता है" से आपका क्या मतलब था?
बोहेमियन

1
Fileमेरे OpenJDK 7.
Dzmitry Lazerka

6

Google द्वारा जिम्फ्स , मेमोरी एनआईओ फाइलसिस्टम में एक है, यह परीक्षण के लिए बहुत अच्छा है।


4

- एक आसान तरीका एक फाइल सिस्टम पूरी तरह से राम के आधार पर उपलब्ध कराने के अपने सिस्टम के तरीके से उपयोग किया जाएगा tempfs लिनक्स, एक पर रैम डिस्क विंडोज पर।


मैं नहीं देखता कि सच्ची फ़ाइल प्रणाली (गति के अलावा) का उपयोग करने से कोई बेहतर कैसे होगा।
Elysium

हाँ, गति (और डिस्क पहनने) मुख्य कारण होगा। क्षमा करें, शायद मैंने आपके लक्ष्य को गलत समझा।
पाओलो एबरमन

1
मेरा लक्ष्य मेरी परीक्षा को आसान बनाना है। मैं वर्तमान में प्रदर्शन से चिंतित नहीं हूं।
Elysium

4

MockFTPServer में फेक फाइलसिस्टम कार्यान्वयन (यूनिक्स / विंडोज) के एक जोड़े के रूप में दिखाई देता है

ऐसा लगता है कि आप इन नकली फाइल सिस्टम कार्यान्वयन का उपयोग किसी भी एफ़टीपी अवधारणाओं से काफी अलग कर सकते हैं। जैसा कि आपने उल्लिखित किया है, मैं बिलकुल उसी पर्सपोज़ के लिए यह कोशिश कर रहा हूँ।


मैं UnixFakeFileSystem का उपयोग कर रहा हूं। मेरे FileSystem अमूर्त के लिए एक नकली कार्यान्वयन के रूप में बहुत अच्छी तरह से काम करना।
डीनो

2

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

यदि आप इसे संभालने के लिए एक निर्भरता इंजेक्शन ढांचे का उपयोग करते हैं, तो यह एक इंटरफ़ेस के फेक कार्यान्वयन के लिए घटकों को स्विच करने की क्षमता को कम करेगा। यदि आप नियंत्रण के व्युत्क्रम के पैटर्न का पालन करते हैं, तो जिस कक्षा में आप यह परीक्षण कर रहे हैं, उसके निर्माणकर्ता में किसी भी निर्भरता से गुजरना आसान परीक्षण भी कर देगा।

public interface IFileSystem {
   IFileHandle Load(string path);
   //etc
}

public class ClassBeingTested {
   public ClassBeingTested(IFileSystem fileSystem) {
      //assign to private field
   }

   public void DoSomethingWithFileSystem() {
       //utilise interface to file system here
       //which you could easily mock for testing purposes
       //by passing a fake implementation to the constructor
   }
}

मुझे आशा है कि मेरा जावा सही है, मैंने लंबे समय में जावा नहीं लिखा है, लेकिन आपको उम्मीद है कि बहाव होगा। उम्मीद है कि मैं इस मुद्दे को कम करके आंका नहीं जा रहा और अत्यधिक सरलीकृत रहा!

बेशक यह सब आपको सही इकाई परीक्षण का मतलब मान रहा है, यानी, कोड की सबसे छोटी संभव इकाइयों का परीक्षण करना, न कि पूरी प्रणाली। एकीकरण परीक्षण के लिए एक अलग दृष्टिकोण की आवश्यकता है।


1
एक नकली फाइल सिस्टम के पास खुद का तर्क होना चाहिए - यह किसी अन्य की तरह एक फाइल सिस्टम है, लेकिन यह केवल मेमोरी में मौजूद है। मैं अपने आप को इस तरह के एक फ़ाइल सिस्टम प्रोग्राम करने से बचना चाहूंगा।
Elysium

आप किस प्रकार के फ़ाइल सिस्टम संचालन की नकल करना चाहते हैं? फ़ाइलों की लॉकिंग? पढ़ना लिखना? या फ़ाइलें खोलने जैसी साधारण सामग्री, निर्देशिकाओं की जाँच करना, फ़ाइलें बनाना मौजूद है?
विक्कीनीलियम्स

ज्यादातर साधारण ऑपरेशन जो यह जाँचने से निपटते हैं कि फाइलें फाइलें हैं या निर्देशिका, यदि वे मौजूद हैं, तो फाइलें बनाने के लिए, फाइलों को हटाने के लिए। यह, निश्चित रूप से, कई फ़ोल्डरों और संचालन का समर्थन करते हुए जैसे कि "इस फ़ाइलनाम से पथ प्राप्त करें", "पूर्ण पथ से सापेक्ष पथ प्राप्त करें", आदि
भटके हुए एलीसियम

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

आपको वास्तव में वह नहीं मिल रहा है जो यहां मांगा जा रहा है। यदि मैं एक नकली फाइल सिस्टम की तलाश कर रहा हूं, तो यह होना ही चाहिए क्योंकि मैंने पहले ही अपने एप में पूरी फाइल प्रणाली को लागू कर दिया है (जैसा कि ओपी की टिप्पणी में कहा गया है)। मैं सिर्फ मेरी परीक्षणों में उपयोग करने के लिए फाइल सिस्टम का एक नकली कार्यान्वयन .. जरूरत है
निगल Elysium

2

Arquillian परियोजना से ShrinkWrap स्मृति FileSystem में एक NIO शिकायत शामिल करने के लिए लग रहा है

आप निम्नलिखित करके मेमोरी फाइलसिस्टम में एक सरल बना सकते हैं:

FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))

क्या यह फ़ाइल का समर्थन करता है: // प्रोटोकॉल, प्रलेखन नहीं पा सकता है ....
मार्को वासापोलो


0

मैं "फेक जावा फाइलसिस्टम" को गुगली कर रहा था और मुझे यह सवाल मिला। दुर्भाग्य से यह सब मुझे मिला है। इसलिए मैंने यह फर्जी फाइलसिस्टम खुद लिखा: https://github.com/dernasherbrezon/mockfs

मैं इसे पढ़ने / लिखने के दौरान IOException का अनुकरण करने के लिए उपयोग कर रहा हूं। IOException "कोई डिस्क स्थान" के कारण उदाहरण के लिए हो सकता है, जो अन्य साधनों द्वारा अनुकरण करना लगभग असंभव है।


-1

यह एक पुराने थोड़ा और इस समाधान linux केवल प्रतीत हो रहा है, लेकिन यह अच्छा लग रहा है https://www.google.co.il/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=tmpfs%20on% 20ubuntu

tmpfs एक इन-मेमोरी मैप्ड डायरेक्टरी है (रिबूट पर डेटा गायब हो जाता है)। एक बार माउंट होने पर, डेटा को इसमें कॉपी किया जा सकता है और मेमोरी से काम किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.