File.separator और रास्तों में स्लैश के बीच अंतर


200

जावा पथ-स्ट्रिंग में उपयोग करने File.separatorऔर सामान्य के बीच क्या अंतर है /?

डबल बैकस्लैश \\प्लेटफ़ॉर्म के विपरीत स्वतंत्रता का कारण नहीं लगता है, क्योंकि दोनों संस्करण विंडोज और यूनिक्स के तहत काम करते हैं।

public class SlashTest {
    @Test
    public void slash() throws Exception {
        File file = new File("src/trials/SlashTest.java");
        assertThat(file.exists(), is(true));
    }

    @Test
    public void separator() throws Exception {
        File file = new File("src" + File.separator + "trials" + File.separator + "SlashTest.java");
        assertThat(file.exists(), is(true));
    }
}

सवाल को फिर से समझने के लिए, अगर /यूनिक्स और विंडोज पर काम करता है , तो किसी को कभी भी उपयोग क्यों करना चाहिए File.separator?


5
@ 'ऐतिहासिक कारण' जैसे कि क्या?
लोर्ने

जवाबों:


245

फ़ाइलों से निपटने के लिए जावा पुस्तकालयों के साथ, आप /सभी प्लेटफार्मों पर सुरक्षित रूप से उपयोग कर सकते हैं (स्लैश, बैकस्लैश नहीं)। लाइब्रेरी कोड आंतरिक रूप से प्लेटफ़ॉर्म-विशिष्ट पथों में अनुवाद करने का काम करता है।

आप File.separatorयूआई में उपयोग करना चाह सकते हैं , हालांकि, क्योंकि यह लोगों को यह दिखाने के लिए सबसे अच्छा है कि जावा के लिए क्या मायने रखता है, बजाय उनके ओएस में क्या अर्थ होगा।

अपडेट : मैं खोज करने के पांच मिनट में, "आप हमेशा एक स्लैश का उपयोग कर सकते हैं" का पता लगाने के लिए प्रलेखित व्यवहार नहीं कर पाए हैं। अब, मुझे यकीन है कि मैंने इसे प्रलेखित देखा है, लेकिन एक आधिकारिक संदर्भ खोजने की अनुपस्थिति में (क्योंकि मेरी स्मृति बिल्कुल सही नहीं है), मैं उपयोग करने के साथ रहना चाहूंगा File.separatorक्योंकि आप जानते हैं कि काम करेगा।


2
यह प्रदर्शन के साथ एक समस्या भी हो सकती है, क्योंकि आप विभाजक से रनटाइम के दौरान किसी और चीज़ में परिवर्तित होने की उम्मीद कर रहे हैं। इसके अलावा, सभी असमर्थित JVM के वहाँ होने की उम्मीद न करें।
जपबुलज़

7
@ टीजे क्राउडर: "मैं पाँच मिनट की खोज में, 'आप हमेशा स्लैश किए गए व्यवहार का उपयोग कर सकते हैं' का पता लगाने में सक्षम नहीं हैं।" यह JVM की एक विशेषता नहीं है, यह Windows NT API की एक विशेषता है।
पॉवरलॉर्ड

12
@Powerlord: अगर विंडोज इसे भी करता है, तो बढ़िया - लेकिन लाइब्रेरी (JVM नहीं) इसे भी करता है। विशेष रूप से, सार्वजनिक एपीआई के माध्यम से प्राप्त पथ को "सामान्य" करने के लिए सभी जगह Fileका उपयोग करता FileSystem.normalizeहै, और लगभग कुछ भी जो पथ पथ के तहत फ़ाइल पथ स्ट्रिंग्स (उदाहरण के लिए FileWriter(String)) Fileसे संबंधित है।
टीजे क्राउडर

9
Java7 के बाद से अब File.separator का उपयोग करने की कोई आवश्यकता नहीं है। यह बहुत सरल और क्लीनर का उपयोग करने के लिए java.nio.file.Paths (Paths.get (पहला, अधिक ...) है।
जादू

6
@jpabluz 'प्रदर्शन के साथ एक समस्या'! क्या आप गंभीर हैं? उपयोग किए जाने वाले फ़ाइलनामों को डिस्क पर रखने पर विचार करते हुए, अनुवाद का रनटाइम प्रभाव पूरी तरह से महत्वहीन है। यह किसी भी जेवीएम द्वारा समर्थित होना चाहिए, क्योंकि यह विनिर्देशन का हिस्सा है File
लोर्ने

316

आप उपयोग करते हैं File.separatorक्योंकि किसी दिन आपका कार्यक्रम एक दूर की जमीन में विकसित मंच पर, अजीब चीजों और अजनबी लोगों की भूमि पर चल सकता है, जहां घोड़े रोते हैं और गाय सभी लिफ्ट का संचालन करती हैं। इस भूमि में, लोगों ने पारंपरिक रूप से फ़ाइल विभाजक के रूप में ":" चरित्र का उपयोग किया है, और इसलिए जेवीएम उनकी इच्छाओं का पालन करता है।


4
हाँ, पोंटी वास्तव में हमें एल्बोनिआ में ले जाता है (आशा है कि उसके पास कोई नुकीला बाल कटवाने नहीं है ;-) (geek
pun

4
"... और गाय सभी लिफ्टों का संचालन करती हैं।" जब मैंने पढ़ा कि बस मैं अपनी कॉफी का एक घूंट नहीं ले रहा था। प्रतिभाशाली।
TJ क्राउडर

8
ऐसे देश में आप नए org.apache.chicken.elevators.OperatorUtility क्लास का उपयोग करेंगे, जो आपकी सुविधा के लिए यह सभी पागलपन पैदा करता है।
ब्रेन

27

हालांकि एक फ़ाइल नाम को संदर्भित करने के File.separator का उपयोग कर overkill है (जो अब तक भूमि से दूर कल्पना, के लिए मुझे लगता है उनके JVM कार्यान्वयन एक जगह लेंगे /के साथ एक :बस खिड़कियों JVM की जगह यह एक साथ की तरह \)।

हालांकि, कभी-कभी आपको फ़ाइल संदर्भ मिल रहा है, इसे नहीं बना रहा है, और आपको इसे पार्स करने की आवश्यकता है, और ऐसा करने में सक्षम होने के लिए, आपको प्लेटफ़ॉर्म पर विभाजक को जानना होगा। File.separator आपको ऐसा करने में मदद करता है।


11

ठीक है, कुछ कोड का निरीक्षण करते हैं।
File.javaलाइनों 428 से 435 में File.<init>:

String p = uri.getPath();
if (p.equals(""))
    throw new IllegalArgumentException("URI path component is empty");

// Okay, now initialize
p = fs.fromURIPath(p);
if (File.separatorChar != '/')
p = p.replace('/', File.separatorChar);

और चलो fs/*(FileSystem)*/.fromURIPath()डॉक्स पढ़ते हैं :

java.io.FileSystem
सार्वजनिक अमूर्त स्ट्रिंग fromURIPath (स्ट्रिंग पथ)
पोस्ट-प्रोसेस को दिए गए URI पथ स्ट्रिंग को आवश्यक रूप से प्रस्तुत करता है। इसका उपयोग win32, जैसे, "/ c: / foo" को "c: / foo" में बदलने के लिए किया जाता है। पथ स्ट्रिंग में अभी भी स्लैश विभाजक हैं; फ़ाइल वर्ग में कोड इस विधि के वापस आने के बाद उनका अनुवाद करेगा।

इसका अर्थ FileSystem.fromURIPath()है कि केवल Windows में URI पथ पर पोस्ट प्रोसेसिंग और क्योंकि अगली पंक्ति में:

p = p.replace('/', File.separatorChar);

यह सिस्टम आश्रित के साथ प्रत्येक '/' की जगह लेता है seperatorChar, आप हमेशा सुनिश्चित कर सकते हैं कि प्रत्येक ओएस में '/' सुरक्षित है ।


8

वैसे, यूनिक्स और विंडोज (पोर्टेबल डिवाइस, आदि) की तुलना में अधिक ओएस हैं, और जावा को पोर्टेबिलिटी के लिए जाना जाता है। इसका उपयोग करने के लिए सबसे अच्छा अभ्यास है, इसलिए जेवीएम यह निर्धारित कर सकता है कि उस ओएस के लिए कौन सा सबसे अच्छा है।


उन OS में से अधिकांश UNIX का कुछ संस्करण चलाते हैं। पुराने मैक शैली :विभाजक लंबे समय से चले गए हैं। ऐसा लगता है कि हर कोई लेकिन विंडोज /अब मानक का उपयोग करता है । और यहां तक ​​कि खिड़कियां अब स्लैश को ठीक से संभालती हैं। cd /windows/systemअपने मुख्य सिस्टम ड्राइव से विंडोज 10 सिस्टम पर प्रयास करें । हालांकि आप अभी भी सिस्टम सेपरेटर का उपयोग करके पथ प्रदर्शित करना चाहते हैं (ताकि अपने उपयोगकर्ताओं को भ्रमित न करें) आप बस /हर जगह फ़ॉरवर्ड-स्लैश का उपयोग कर सकते हैं और आश्वस्त रहें कि आपका कोड कहीं भी काम करेगा कि आप इसे तैनात करने की संभावना रखते हैं।
शैडो मैन

7

यद्यपि यह रास्ते में बहुत अंतर नहीं करता है, यह वापस रास्ते पर करता है।

सुनिश्चित करें कि आप नई फ़ाइल (स्ट्रिंग पथ) में या तो '/' या '\' का उपयोग कर सकते हैं, लेकिन File.getPath () केवल आपको उनमें से एक देगा।


थोड़ा सुधार ... विंडोज में आप आगे /या पीछे \\ स्लैश का उपयोग कर सकते हैं । लेकिन कहीं और, आप बेहतर स्लैश का उपयोग कर रहे हैं /या आपके पास मुद्दे होंगे।
शैडो मैन

6

पार्टी के लिए देर से। मैं JDK 1.8 और ग्रहण MARS 1. के साथ विंडोज 10 पर हूं।
मुझे लगता है कि

getClass().getClassLoader().getResourceAsStream("path/to/resource");

काम करता है और

getClass().getClassLoader().getResourceAsStream("path"+File.separator+"to"+File.separator+"resource");

काम नहीं करता है और

getClass().getClassLoader().getResourceAsStream("path\to\resource");

काम नहीं करता। अंतिम दो बराबर हैं। इसलिए ... मेरे पास File.separator का उपयोग नहीं करने का अच्छा कारण है।


6
इस पंक्ति में getClass().getClassLoader().getResourceAsStream("path\to\resource");, सारणीकरण ( \t) और एक गाड़ी वापसी ( \r) हैं।
स्टेफेन

9
यह सवाल का एक अलग परिदृश्य है। ClassLoader का getResourceAsStream विधि एक फ़ाइल पथ नहीं लेती है, लेकिन एक संसाधन नाम जो फ़ाइल सिस्टम पर हो सकता है या नहीं भी हो सकता है और केवल संसाधन पथ विभाजक के रूप में '/' को स्वीकार करने के रूप में प्रलेखित है
16

@ स्टेफ़न वहाँ कोई अजीब भागने वाला है, क्योंकि File.separatorएक बैकस्लैश है। यह केवल हार्ड-कोडेड स्ट्रिंग्स में है जहां इसे एक भागने चरित्र के रूप में माना जाता है जहां आपको बैकस्लैश से बचने की आवश्यकता होती है। आप किसी पाठ फ़ाइल में चरित्र संग्रहीत हैं कर दिया है, या एक में charया Stringतो आप इसे एक 2 बार से बचने के लिए के रूप में यह पहले से ही उम्मीद बैकस्लैश चरित्र में बदल दिया गया है की जरूरत नहीं है। इसे अपने लिए देखने की कोशिश करें:String backslash = "\\"; System.out.println("welcome" + backslash + "to" + backslash + "reality");
शैडो मैन

2
@ स्टीफन ओह, मैं देख रहा हूँ ... आप तीसरी पंक्ति के बारे में बात कर रहे थे। तुम सही हो। उस पंक्ति में (एक हार्ड-कोडेड स्ट्रिंग) आपको भागने के चरित्र से बचने की आवश्यकता होगी। मेरी नज़र दूसरी पंक्ति में रुक गई और मैंने पहली बार तीसरी पंक्ति को भी नोटिस नहीं किया।
शैडो मैन

3

पोर्टेबिलिटी सादा और सरल।


हाँ, पोर्टेबिलिटी के लिए, बैकस्लैश का उपयोग करें। आगे स्लैश /या सिस्टम विभाजक का उपयोग करें File.separator। वो दोनों हर जगह काम करते दिखते हैं। जबकि File.separatorहर जगह काम करने की गारंटी है, साधारण स्लैश /भी हर जगह काम करने लगता है। अगर यह कहीं काम नहीं करता है, तो मुझे इसके बारे में सुनना अच्छा लगेगा। मुझे विश्वास है कि यह सभी प्रणालियों पर काम करेगा। बहुत कम से कम, मुझे अभी तक कहीं भी /नहीं मिला है जो काम नहीं करता है (मैक ओएसएक्स, विंडोज, * निक्स, एंड्रॉइड, आईओएस - मैंने प्री ओएसएक्स मैक का उपयोग नहीं किया है जो ":" एक विभाजक के रूप में, हालांकि, ओएस / 2, नेक्सटी, या वास्तव में प्राचीन ओएस के किसी भी)।
शैडो मैन

1

"जावा SE8 फॉर प्रोग्रामर्स" का दावा है कि जावा या तो सामना करेगा। (पीपी। 480, अंतिम पैराग्राफ)। उदाहरण का दावा है कि:

c:\Program Files\Java\jdk1.6.0_11\demo/jfc

बस ठीक हो जाएगा। अंतिम (यूनिक्स-शैली) विभाजक पर ध्यान दें।

यह कठिन है, और शायद त्रुटि-प्रवण है, लेकिन यह वही है जो वे (डीटेल और डीटेल) का दावा करते हैं।

मुझे लगता है कि जावा के बजाय लोगों के लिए भ्रम इस कारण (मिस?) सुविधा का उपयोग नहीं करने के लिए पर्याप्त है।


1

जैसा कि सज्जनों ने भिन्न विवरण के साथ अंतर का वर्णन किया है।

मैं कई ओएस पर तैनाती की संभावना के साथ एक कार्यक्रम में फ़ाइलों के साथ काम करते समय , Apache कॉमन्स io एपीआई के उपयोग की सिफारिश करना चाहूंगा FilenameUtils


0

फ़ाइल या निर्देशिका के लिए पथनाम होस्ट सिस्टम के नामकरण सम्मेलनों का उपयोग करके निर्दिष्ट किया गया है। हालाँकि, फ़ाइल वर्ग प्लेटफ़ॉर्म-निर्भर स्थिरांक को परिभाषित करता है जिसका उपयोग प्लेटफ़ॉर्म-स्वतंत्र तरीके से फ़ाइल और निर्देशिका नामों को संभालने के लिए किया जा सकता है।

Files.seperator उस चरित्र या स्ट्रिंग को परिभाषित करता है जो डायरेक्टरी और फ़ाइल com- पोर्टर को एक पाथनाम में अलग करती है। यह विभाजक क्रमशः यूनिक्स, विंडोज और मैकिंटोश के लिए '/', '\' या ':' है।


मैकिंटोश के लिए ":" प्राचीन है। OSX के बाद से, मैक भी "/" (फॉरवर्ड स्लैश) का उपयोग करता है क्योंकि यह हुड के तहत एक मानक UNIX फाइल सिस्टम के साथ UNIX का एक रूप चला रहा है।
शैडो मैन


0

File.separator का प्रयोग करके Ubuntu ने फाइलों को निर्देशिकाओं के बजाय "\" नाम दिया है। हो सकता है कि मैं आलसी हो रहा हूं कि मैं कैसे फाइलें (और निर्देशिका) बना रहा हूं और इसे टाल सकता था, भले ही, यह नाम पर "\" फाइलों से बचने के लिए हर बार "/" का उपयोग करें।


0

यदि आप लिनक्स सेपरेटर का उपयोग करके कुछ तैयार पथ (डेटाबेस में सहेजे गए, उदाहरण के लिए) से एक फ़ाइल बनाने की कोशिश कर रहे हैं, तो मुझे क्या करना चाहिए?

हो सकता है कि केवल फ़ाइल बनाने के लिए पथ का उपयोग करें:

new File("/shared/folder/file.jpg");

लेकिन विंडोज एक अलग विभाजक ( \) का उपयोग करता है । तो, क्या वैकल्पिक स्लैश विभाजक को प्लेटफ़ॉर्म पर स्वतंत्र रूप से परिवर्तित किया गया है? पसंद:

new File(convertPathToPlatformIndependent("/shared/folder"));

इस विधि में convertPathToPlatformIndependentशायद "/" द्वारा किसी प्रकार का विभाजन होगा और File.separator के साथ जुड़ जाएगा।

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

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