क्या फ़ाइल पथ स्ट्रिंग्स को संयोजित करने का एक पारंपरिक तरीका है?


34

एक उदाहरण में:

var assets = "images/"

var sounds = assets+"sounds/"

क्या फ़ाइल पथ के पीछे स्लैश रखना अधिक पारंपरिक है?

var assets = "/images"

var sounds = assets+"/sounds"

क्या एक और तरीका है जो एक अच्छा सामान्य अभ्यास है?


जावा में स्टैटिक स्ट्रिंग्स File.separator और File.pathSeparator है जो प्रासंगिक लगता है। इस तरह आप सभी प्लेटफार्मों पर सुरक्षित हैं
एवरोरल

1
@Everlor आपको शायद ही कभी उपयोग करने की आवश्यकता होती है File.separator, Fileऔर PathAPI दोनों को स्वीकार करते हैं /और `\`।
kapex

2
क्या आप इंगित कर सकते हैं कि आप किस भाषा का प्रयोग कर रहे हैं, कृपया यह शायद इसी टैग को जोड़ने के लायक है।
क्रिस्टोफर क्रेतुज़िग

@ChristopherCreutzig मैं जावा का उपयोग कर रहा हूं - हालांकि मैं पूछ रहा था कि क्या स्ट्रिंग्स में फ़ाइल निर्देशिकाओं के संयोजन के लिए कोई सामान्य रूप से उपयोग किए जाने वाले सम्मेलन थे। जाहिरा तौर पर कुछ सामान्य रूप से स्वीकृत नियम हैं और कुछ सामान्य ज्ञान शामिल हैं, लेकिन यह भाषा से भाषा में थोड़ा भिन्न होता है।
iiridescent

1
यूनिक्स दुनिया में (और urls में) इसके लायक क्या है, एक पथ के बीच में कई फॉरवर्ड स्लैश को एक एकल के लिए समान रूप से व्यवहार किया जाता है, इसलिए यदि आप अधिक स्लैश के पक्ष में गलत करते हैं तो कुछ भी बुरा नहीं होगा। यह एकल यूनिक्स विशिष्टता का हिस्सा है; इस उत्तर को देखें - unix.stackexchange.com/a/1919/21161
yoniLavi

जवाबों:


37

लगभग हर प्रमुख प्रोग्रामिंग भाषा में आपके लिए निर्देशिका विभाजकों को संभालने के लिए एक पुस्तकालय है। आपको उनका लाभ उठाना चाहिए। यह आपके कोड को सरल करेगा और बग्स को रोकेगा

मेरे अनुभव में, तार के संयोजन के लिए सामान्य कारण यह है कि वे विभिन्न स्रोतों से आते हैं। कभी-कभी यह एक कॉन्फ़िगरेशन फ़ाइल से अलग-अलग टुकड़े होते हैं। कभी-कभी यह एक फ़ंक्शन तर्क के साथ एक निरंतर संयोजन होता है। किसी भी और सभी मामलों में, जब वे विभिन्न स्रोतों से आते हैं, तो आपको अलग-अलग संभावित मामलों पर विचार करना होगा:

  • दोनों सिरों में एक विभाजक हो सकता है: "images/"और"/sounds"
  • केवल एक के पास एक विभाजक है: "images"और "/sounds"या "images/"और"sounds"
  • न ही एक विभाजक है: "images"और"sounds"

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

अधिकांश प्रमुख भाषाएँ आपके लिए ऐसा करने का एक तरीका प्रदान करती हैं जो पहले से ही कई मामलों को संभालती है:

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

यह अतिरिक्त रूप से मदद करता है अगर आपको विभिन्न ऑपरेटिंग सिस्टम के समर्थन की कोई आवश्यकता है। इन वर्गों को सही विभाजक चुनने के लिए लगभग सर्वव्यापी खाते हैं। पुस्तकालयों में आमतौर पर ओएस सम्मेलनों को फिट करने के लिए पथों को सामान्य करने का एक तरीका होता है।

इस घटना में कि आपकी प्रोग्रामिंग भाषा में आसानी से उपलब्ध लाइब्रेरी नहीं है, आपको एक विधि लिखनी चाहिए जो इन सभी मामलों को संभालती है और इसे उदारतापूर्वक और परियोजनाओं में उपयोग करती है।

यह "मान्यताओं को न बनाएं" और "मदद करने वाले उपकरणों का उपयोग करने" की श्रेणी में आता है।


2
.NET का Path.Combine नहीं टूटा है। बस यह विभाजक फ़ीड नहीं है। सुनिश्चित करें कि आप दस्तावेज़ को पढ़ते हैं, यदि दूसरा तर्क एक रूट पथ है तो इसका एक परिभाषित परिणाम है। आप इसे पसंद नहीं कर सकते हैं लेकिन इसका मतलब यह नहीं है कि यह टूट गया है।
एर्नो

4
सुनिश्चित करें कि आपने यह सुनिश्चित करने के लिए प्रलेखन को पढ़ा है कि यह बहुत चालाक होने की कोशिश नहीं कर रहा है। मैंने एक बार एक पुस्तकालय का उपयोग किया था जो एक * nix प्रणाली के C:\Documents and Settings\Adminसाथ सफलतापूर्वक my folder:document.txtनिर्माण कर सकता था /home/admin/my folder/document.txt- एक प्यारा चाल, लेकिन वास्तविक दुनिया में, हेयुरिस्टिक्स में उनके द्वारा तय किए गए से अधिक कीड़े शामिल थे।
मार्क

1
इसके अलावा, जावा के लिए, Paths.get()बस किसी Stringएक Pathवस्तु में परिवर्तित होता है । रास्तों में शामिल होने के लिए, आप उपयोग करेंगे Path.resolve(), जो दूसरे Pathया एक में ले सकते हैं StringPathकक्षा में अन्य विधियाँ हैं जो आगे चलकर विभिन्न तरीकों से जुड़ने की अनुमति देती हैं।
कैट

1
मेरा बुरा, ऐसा लगता है कि मैंने डॉक्स को Pathsबहुत अच्छी तरह से नहीं पढ़ा है ।
कैट

1
PowerShell पर, .NET पद्धति का एक विकल्प [System.IO.Path]::Combine("abc", "\def")जिसमें वर्णित व्यवहार है, वह cmdlet है Join-Path "abc" "\def"जो देता है "abc\def"
जेपी स्टिग नीलसन

38

जावा में, उत्तर "न तो उपरोक्त में से" होगा। सबसे अच्छा अभ्यास java.io.Fileवर्ग का उपयोग करते हुए पथनामों को इकट्ठा करना होगा ; जैसे

File assets = new File("images");
File sounds = new File(assets, "sounds");

Fileप्लेटफ़ॉर्म-विशिष्ट पथनाम विभाजक का वर्ग भी ध्यान रखता है।

इस बात का एक अलग मुद्दा है कि क्या आपका पथनाम स्लैश से शुरू होना चाहिए या नहीं। लेकिन यह सबसे अच्छा अभ्यास की तुलना में शुद्धता के साथ करने के लिए अधिक है। एक पथनाम जो स्लैश के साथ शुरू होता है, एक पथनाम के लिए कुछ अलग होता है जो नहीं करता है !!


कोर (ECMA) जावास्क्रिप्ट लाइब्रेरी में pathname हैंडलिंग के लिए स्पष्ट समर्थन नहीं है, लेकिन (कम से कम) Node.js पथ मॉड्यूल के माध्यम से समर्थन प्रदान करता है।


4
ऐसा ही कुछ। नेट फ्रेमवर्क भाषाओं और किसी अन्य के लिए भी होता है जो फाइलसिस्टम क्लासेस प्रदान करते हैं।
जेम्स स्नेल

3
धन्यवाद! यह सबसे उपयोगी उत्तर की तरह लग रहा था, भले ही भाषा विशिष्ट हो, पुस्तकालयों को सामान्य रूप से अन्य भाषाओं के लिए मौजूद होना चाहिए, जैसे .NET और C ++;
१६ पर आइराइडेसेंट

3
वास्तव में, कोई भी कोड जो लाइब्रेरी का उपयोग नहीं करता है, उसे कोड समीक्षा में खारिज कर दिया जाना चाहिए। दुर्लभ अवसर में कोई पुस्तकालय मौजूद नहीं है, इसका उत्तर कच्चे तारों को चिपकाने के बजाय खुद को लिखना होगा।
रोबोट

C ++ में Boost :: Filesystem है , और C # में System.IO.Path है
Mooing Duck

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

21

ध्यान दें कि .NET में आपको Path.Combine विधि का उपयोग करना चाहिए।

var path = System.IO.Path.Combine("assets", "sounds");

इसका कारण यह है कि यह फ़ोल्डर नामों का निर्माण करते समय उपयोग किए जाने वाले सही वर्णों को 'जानता है' ।

यह पूर्व या पोस्ट फिक्सिंग की 'समस्या' को दूर करता है।


4
os.path.join मूल रूप से अजगर के लिए भी यही काम करता है
StarWeaver

ध्यान दें कि path.combine आपको सेपरेटर के बारे में चिंता करने के व्यवसाय से बाहर नहीं निकालता है: stackoverflow.com/questions/53102/…
jmoreno

1
@jmoreno - मेरे उदाहरण में कोई विभाजक नहीं हैं। आपके द्वारा लिंक किए गए प्रश्न में हार्ड कोडित विभाजक हैं और यदि मौलिक रूप से गलत है क्योंकि दूसरा मार्ग एक निरपेक्ष पथ है।
Erno

हालांकि, इसके साथ सावधान रहें। मैं नेट के बारे में अनिश्चित हूँ, लेकिन os.path.join('src', '../../../your_secret_stuff') है पायथन में मान्य; दूसरे शब्दों में, उपयोगकर्ता इनपुट पर इन विधियों का नेत्रहीन उपयोग न करें।
सपि

@sapi - बेशक, उपयोगकर्ता इनपुट को हमेशा स्वच्छता होना चाहिए लेकिन यह प्रोग्रामर की जिम्मेदारी है, एपीआई की नहीं।
एरनो

5

रास्तों का निर्माण करते समय मैं अक्सर एक फ़ंक्शन का उपयोग करता हूं जो अनुगामी स्लैश जोड़ता है यदि यह पहले से ही नहीं है। तब रास्ते बनाए जा सकते हैं जैसे:

filename := fs( 'assets') + fs( 'images') + fs( 'icons') + 'some.png';

जहाँ fs () अपनी ज़रूरत के हिसाब से एक अनुगामी स्लैश जोड़ता है।


5

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

var absolutepath = "/my/path/";
var relativepath = "css/";
var filename = "test.css";
var relativepathtofilename = "js/test.js";

var a = absolutepath + relativepath + filename; //Output: /my/path/css/test.css
var b = absolutepath + relativepathtofilename;  //Output: /my/path/js/test.js

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


इसने संभवतः मेरे मूल प्रश्न का सबसे अच्छा उत्तर दिया, मुझे लगता है कि मैं फ़ाइल पथ को बेहतर तरीके से समझता हूं, हालांकि स्टीफन सी और एर्नो ने कहा, भाषा पुस्तकालय एक सर्वश्रेष्ठ पहली शर्त है। हालांकि यह सम्मेलन को बेहतर बताता है। धन्यवाद!
इरिडसेंट

फ़ाइल सिस्टम पथ या URL?
MrWhite

1
सभी इरादों और उद्देश्यों के लिए, आप इसे उरई पर भी लागू कर सकते हैं। एक निरपेक्ष यूरी एक प्रोटोकॉल के साथ शुरू होगा, लेकिन इसके अलावा यह वही होगा जो मुझे लगता है।
सुमुरै 8

सुनिश्चित नहीं है कि आपका आउटपुट कैसे काम कर रहा है। जब मैं इसे प्राप्त करता हूं:var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
डेमोन

1
@Damon मैंने एक संपादन किया। absolutepathएक स्लेश के साथ समाप्त होना चाहिए था, क्योंकि यह एक रास्ता है। किसी तरह मैंने अनदेखा किया कि जब मैंने यह लिखा था।
सुमुरै

4

मुझे लगता है कि रास्तों को कैसे लागू किया जाए, इस पर कोई जादू या "सामान्य अभ्यास" नहीं है, लेकिन निश्चित रूप से स्ट्रिंग संघटन जाने का तरीका नहीं है। आप मामलों से निपटने के लिए अपना स्वयं का एपीआई विकसित कर सकते हैं, लेकिन इसके लिए कुछ प्रयास की आवश्यकता हो सकती है। विशेष रूप से, आपको विभिन्न प्लेटफार्मों के बारे में सावधान रहना चाहिए। उदाहरण के लिए, विंडोज \में विभाजक है जबकि यूनिक्स-आधारित सिस्टम /में विभाजक है।

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


3
Windows वास्तव /में पथ फ़ाइल नाम सीमांकक के रूप में समर्थन करता है। इसके लिए कमांड लाइन में क्वर्की की जरूरत होती है, लेकिन I / O एपीआई फाइल आगे स्लैश के साथ अच्छी तरह से काम करती है।
रुस्लान

en.wikipedia.org/wiki/… "विंडोज सिस्टम एपीआई स्लैश स्वीकार करता है, और इस प्रकार उपरोक्त सभी संयुक्त राष्ट्र के उदाहरणों पर काम करना चाहिए। लेकिन विंडोज पर कई एप्लिकेशन अन्य उद्देश्यों के लिए स्लैश की व्याख्या करते हैं या इसे एक अमान्य चरित्र के रूप में मानते हैं, और इस तरह आपको आवश्यकता होती है। बैकस्लैश में प्रवेश करने के लिए - विशेष रूप से cmd.exe शेल (जिसे अक्सर "टर्मिनल" कहा जाता है क्योंकि यह आमतौर पर टर्मिनल विंडो में चलता है)।
मिंग डक

0

मेरी व्यक्तिगत प्राथमिकता यह है:

var assets = "/images"

var sounds = assets+"/sounds"

मैं हमेशा निरपेक्ष रास्तों ( /images/...) का उपयोग करता हूं , इससे मुझे कम त्रुटि महसूस होती है। यह उपयोग करने के लिए अधिक मूर्ख प्रमाण var sounds = assets+"/sounds"भी है क्योंकि यदि assetsकोई अनुगामी स्लेश था और आप के साथ समाप्त हो गया था /images//sounds, तब भी इसका समाधान होगा /images/sounds। एक अस्वीकरण कि यह आपके अनुरोध हैंडलर पर निर्भर करता है। अपाचे इसे ठीक से संभालने के लिए लगता है (कम से कम कुछ संस्करणों / कॉन्फ़िगरेशनों को देखें, http://www.amazon.com//gp//site-directory//ref=nav_sad )। दूसरे तरीके से आप खत्म हो जाएंगे /imagessounds, इतना मूर्ख प्रमाण नहीं है :) डबल स्लैश के लिए जाँच करने और उन्हें साफ करने का विकल्प भी है। अन्य दृष्टिकोण के साथ एक विकल्प नहीं है।


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

@BartvanIngenSchenau मैं पूरी तरह से आपके साथ सहमत हूं और मैं उन्हें वर्षों से बुला रहा हूं, लेकिन हर बार जब मैं फ्रंट एंड डेवलपर द्वारा लिखे गए एक लेख को पढ़ता हूं तो वे उन्हें रिश्तेदार पथ के रूप में संदर्भित करते हैं। मैं अनुमान नहीं लगाना चाहता था इसलिए मुझे लगता है कि मैंने दो बुराइयों को कम किया है ...? अब जब मुझे पता है कि मेरे पास कुछ लोग हैं, तो मैं अपना जवाब अपडेट करूंगा :)
rpaskett

2
वेब डेवलपर्स के लिए, /somewhereएक सापेक्ष पथ है क्योंकि इसमें होस्ट शामिल नहीं है, इसलिए ब्राउज़र वर्तमान पृष्ठ के होस्ट के आधार पर इसे देखेगा ... वेब दुनिया में, http://here/somewhereएक पूर्ण यूआरआई है, और /somewhereelseउसी के सापेक्ष है। फ़ाइल-सिस्टम की दुनिया में, /somewhereनिरपेक्ष है, मूल से आ रहा है /, और "कहीं" वर्तमान कार्यशील निर्देशिका के सापेक्ष है।
रोब

3
@RobY, rpaskett: RFC3986 (RFC जो URIs को परिभाषित करता है) द्वारा जाना जाता है , http://here/somewhereएक निरपेक्ष पथ वाला URI है, एक पूर्ण पथ के /somewhereसाथ somewhere/elseएक सापेक्ष संदर्भ है और एक सापेक्ष पथ के साथ एक सापेक्ष संदर्भ है। जाहिर है, उन हलकों में "रिश्तेदार पथ" का उपयोग एक रिश्तेदार संदर्भ को संदर्भित करने के लिए किया जाता है।
बार्ट वैन इनगेन शेनौ

1
@BartvanIngenSchenau: खिड़कियों में, एक रास्ता जो एक स्लैश से शुरू होता है, एक रिश्तेदार पथ है, और CWD के सापेक्ष है। en.wikipedia.org/wiki/…
डक

0

स्मालटाक में स्ट्रिंग में / पद्धति को परिभाषित करना सीधा है ताकि यह इस तरह से काम करे:

'assets' / 'sounds' => 'assets/sounds'.
'assets/' / 'sounds' => 'assets/sounds'.
'assets' / '/sounds' => 'assets/sounds'.
'assets/' / '/sounds' => 'assets/sounds'.

यहाँ विधि का एक सरल कार्यान्वयन है (आप इसे बेहतर बना सकते हैं):

/ aString
    | slash first second |
    slash := Directory separator.
    first := self.
    (first endsWith: slash) ifTrue: [first := first allButLast].
    second := aString.
    (second beginsWith: slash) ifTrue: [second := second allButFirst].
    ^first , slash , second

नोट : यदि आप भी इस तरह के रूप में सीमा मामलों के लिए बेहतर ध्यान देना चाहते हो सकता है '' / '', 'x/' / ''उचित व्यवहार का निर्धारण करने के लिए, आदि।

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