Dosya yolu dizelerini birleştirmenin geleneksel bir yolu var mı?


34

Bir örnekte:

var assets = "images/"

var sounds = assets+"sounds/"

Eğik çizgiyi bir dosya yolunun arkasına koymak daha mı geleneksel?

var assets = "/images"

var sounds = assets+"/sounds"

İyi bir ortak uygulama olan başka bir yöntem var mı?


Java, statik dizgelere File.separator ve File.pathSeparator ile alakalı gelir. Bu şekilde tüm platformlarda
güvendesiniz

1
@Evorlor Nadiren kullanmanız gerekir File.separator, Fileve PathAPI'ler hem de /`\` kabul eder .
kapex

2
Lütfen hangi dili kullandığınızı belirtir misiniz? Muhtemelen ilgili etiketi eklemeye değer.
Christopher Creutzig,

@ChristopherCreutzig Java kullanıyorum - dosya dizinlerini dizelerde birleştirmek için sık kullanılan herhangi bir konvansiyon olup olmadığını soruyordum. Görünüşe göre, genel olarak kabul edilmiş birkaç kural var ve bazı sağduyular dahil, ancak dilden dile biraz değişiyor.
iiridescent

1
Neye mal olursa olsun, unix dünyasında (ve url'lerde), bir yolun ortasındaki çoklu eğik çizgiler tek bir çizgiyle aynı şekilde işlem görür, bu nedenle daha fazla eğik çizginin yanına düşerseniz kötü bir şey olmaz. Tekli Unix Spesifikasyonunun bir parçasıdır; bu cevabı gör - unix.stackexchange.com/a/1919/21161
yoniLavi

Yanıtlar:


37

Neredeyse her büyük programlama dilinde, dizin ayırıcıları sizin için idare edecek bir kütüphane bulunur. Onları güçlendirmelisin. Bu, kodunuzu basitleştirir ve hataları önler .

Tecrübelerime göre, bunun gibi dizeleri birleştirmenin genel nedeni, farklı kaynaklardan gelmeleridir. Bazen bir yapılandırma dosyasından farklı parçalar olabilir. Bazen bir fonksiyon argümanı ile birleştirerek sabit. Her durumda ve farklı kaynaklardan geldiklerinde, birleştirilecek uçlardaki ayırıcılarla ilgili birkaç olası durumu göz önünde bulundurmalısınız:

  • Her iki ucunda bir ayırıcı olabilir: "images/"ve"/sounds"
  • Sadece bir bir ayırıcı vardır: "images"ve "/sounds"ya "images/"ve"sounds"
  • Hiçbirinde bir ayırıcı yok: "images"ve"sounds"

Her bölümün farklı bir kaynaktan geldiği gerçeği, bir başkasına herhangi bir düşünce vermesi durumunda, her kaynağın hangi sözleşmeleri takip edeceği konusunda kendi fikirlerinin olabileceği anlamına gelir! Kodunuzu her ne çağırıyorsa, bunun için endişelenmenize gerek yoktur . Kodunuz tüm durumları ele almalıdır, çünkü birisi sözleşmenizi ihlal edecek . Bu, bir hatanın nedenini araştırarak ve düzeltmeyi boşa harcayarak sonuçlanacaktır. Bir iş arkadaşının, bir yapılandırma dosyasında yolların nasıl biçimlendirilmesi gerektiği konusunda bir varsayımda bulunduğu bazı nahoş durumlar yaşadım, bu da kodu araştırıp ne beklediğini (veya kodu düzeltmek zorunda kaldığım) anladım.

Çoğu ana dil, sizin için zaten birçok durumu ele alan bir yöntem sunar:

Bunlarla ilgili bir uyarı var. Bunların bir kısmı, ikinci argümandaki öncü bir dizin ayırıcısının bir kök yoluna atıfta bulunduğunu ve bunun ilk argümanın tamamen bırakılması gerektiği anlamına geldiğini düşünmektedir. Bunun neden faydalı olduğunu bilmiyorum; benim için sadece sorunlara neden olur. Asla iki yol bölümünü birleştirmek ve ilk kısmı atılmak istemedim. Özel durumlar için belgeleri dikkatlice okuyun ve gerekiyorsa, özel kullanımları yerine, bunlarla ne istediğinizi yapan bir sarıcı yazın.

Bu, farklı işletim sistemlerini destekleme gereksiniminiz varsa, ayrıca yardımcı olur. Bu sınıflar neredeyse her yerde, doğru ayırıcıyı seçmekten sorumludur. Kütüphaneler genellikle işletim sistemi sözleşmelerine uyacak şekilde normalize etme yollarına da sahiptir.

Programlama dilinizin hazır bir kütüphaneye sahip olmaması durumunda, tüm bu davaları ele alan ve bunları serbestçe ve projeler arasında kullanan bir yöntem yazmalısınız .

Bu, "varsayımlarda bulunma" ve "size yardımcı olacak araçları kullanma" kategorisine giriyor.


2
.NET'in Path.Combine bozuk değil. Sadece ayırıcıları beslemeyin. İkinci argüman bir kök yolsa, tanımlanmış bir sonucu olan dokümanları okuduğunuzdan emin olun. Hoşunuza gitmeyebilir ama bu kırıldığı anlamına gelmez.
Erno

4
Akıllıca görünmediğinden emin olmak için belgeleri okuduğunuzdan emin olun. Bir keresinde başarıyla birleştirmek olabilecek bir kütüphane kullanılan C:\Documents and Settings\Adminile my folder:document.txtüretmek için bir * Nix sistemde /home/admin/my folder/document.txt- şirin hile, fakat gerçek hayatta heuristic'ler onlar sabit daha fazla hata tanıtıldı içeriyordu.
Mark

1
Ayrıca, Java için Paths.get()yalnızca Stringbir Pathnesneyi bir nesneye dönüştürür . Yollara katılmak Path.resolve()için, bir Pathveya daha fazla sürebilen, kullanacaksınız String. Diğer yöntemler var Pathayrıca çeşitli şekillerde yolları katılma izin sınıfa.
Kat

1
Benim hatam, görünüşe göre doktorları Pathsçok iyi okumadım .
Kat

1
PowerShell, .NET metoduna bir alternatif üzerinde [System.IO.Path]::Combine("abc", "\def")tarif edilen davranışı vardır, komutudur Join-Path "abc" "\def"verir "abc\def".
Jeppe Stig Nielsen,

38

Java'da cevap "yukarıdakilerin hiçbiri" olmazdı. En iyi uygulama, java.io.Filesınıfı kullanarak yol adlarını bir araya getirmektir ; Örneğin

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

FileSınıfı da platforma özel yol adı ayırıcılar ilgilenir.

Yol adınızın bir eğik çizgiyle başlayıp başlamamasına ilişkin ayrı bir sorun var. Ancak bu, en iyi uygulamadan daha doğrulukla yapmaktır. Bir eğik çizgiyle başlayan bir yol adı olmayan bir yol adından farklı bir şey anlamına gelir !


Çekirdek (ECMA) Javascript kitaplığında yol adı işleme için kesin destek yoktur, ancak (en azından) Node.js, Path modülü aracılığıyla destek sağlar.


4
Benzer bir şey de .Net Framework dilleri ve dosya sistemi sınıfları sunan diğerleri için de geçerlidir.
James Snell

3
Teşekkür ederim! Bu en yararlı cevap gibi gözüküyordu, ancak dile özgü olmasına rağmen, .NET ve C ++ gibi genel olarak diğer diller için kütüphaneler mevcut olmalı;
iiridescent

3
Gerçekten de, kütüphane kullanmayan herhangi bir kod kod incelemesinde reddedilmelidir. Nadiren hiçbir kütüphane bulunmadığında, cevap ham dizeleri yapıştırmak yerine kendiniz yazmak olacaktır.
Robotu


Python var os.path.join. PowerShell'de join-path. Bu cevaba bir şey eklerdim. Birden fazla parçada dosya yoluna ihtiyacınız varsa, dosya yollarının herhangi birinin belirli yerlerde olduğu hakkında varsayımlar yaparsanız , kodunuzu çok kırılgan hale getirdiğini buldum . Bu sınıfları kullanmak yalnızca taşınabilirliğe yardımcı olmakla kalmaz, aynı zamanda tüm olası kenar kasalarını da işler (birleştirilecek her iki uçta eğik çizgi, sadece bir yana eğik çizgi, hiç eğik çizgi olmadan). Bir yapılandırma dosyasında dosya yollarını bıraktığınızda bu esneklik paha biçilmezdir .
jpmc26

21

.NET'te Path.Combine yöntemini kullanmanız gerektiğini unutmayın.

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

Bunun nedeni , klasör adlarını oluştururken kullanılacak doğru karakterleri 'bilmesidir' .

Bu, ön montaj veya montaj sonrası 'problemini' ortadan kaldırır.


4
os.path.join aslında python için de aynı şeyi yapar
StarWeaver

Path.combine'nin ayırıcı hakkında endişelenmenize neden olmadığına dikkat edin: stackoverflow.com/questions/53102/…
jmoreno

1
@jmoreno - Örneğimde NO ayırıcısı var. Bağlandığınız sorunun kodlanmış ayırıcıları vardır ve temelde yanlışsa, ikinci yol mutlak bir yoldur.
Erno

Yine de buna dikkat et. Ben .NET konusunda emin değilim, ama os.path.join('src', '../../../your_secret_stuff') bir Python geçerli; Başka bir deyişle, kullanıcı girişinde bu yöntemleri kör kullanmayın.
sapi

@sapi - Elbette, kullanıcı girişi her zaman sterilize edilmelidir, ancak API'nin değil programcının sorumluluğundadır.
Erno

5

Yolları oluştururken, zaten orada değilse, sondaki eğik çizgiyi ekleyen bir işlev kullanırım. Sonra yollar şöyle inşa edilebilir:

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

fs () gerektiğinde sonunda eğik çizgi ekler.


5

Klasörler ve dosyalar yalnızca bir açıdan farklılık gösterir: klasörler, dosyaların bulunmadığı bir eğik çizgiyle sona erer. Ayrıca, mutlak yollar /göreceli yolların olmadığı bir yerden başlar . Bunu sürekli kullanırsanız birleştirici yollar ve dosyalar bir sorun olmamalıdır.

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

İki mutlak yolu bir araya getirmek bir anlam ifade etmiyor, çünkü ikinci yol ilk yola göre olmalıdır. İki göreceli yolu bir arada birleştirmek bir sorun değildir, ancak program göreceli yolun nerede olduğunu bilmiyorsa, tanımsız davranışa neden olabilir.


Bu muhtemelen asıl soruma en iyi şekilde cevap verdi, sanırım dosya yollarını daha iyi anlıyorum, Stephen C ve Erno'nun dediği gibi, dil kütüphaneleri en iyi ilk bahis. Bu kongre daha iyi açıklar. Teşekkür ederim!
iiridescent

Dosya sistemi yolları veya URL'leri?
MrWhite

1
Tüm amaç ve amaçlarınız için, bunu uri'nin içinde de uygulayabilirsiniz. Mutlak bir uri bir protokolle başlayacak, ama bunun yanında bence de aynı olurdu.
Sumurai8

Çıktınızın nasıl çalıştığından emin değilim. Bunu yaptığımda alıyorum:var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
Damon

1
@Damon Bir düzenleme yaptım. absolutepathbir eğik çizgiyle bitmiş olmalıydı, çünkü bu bir yol. Her nasılsa bunu yazarken bunu göz ardı ettim.
Sumurai8

4

Yolların nasıl uygulanacağı konusunda sihir ya da "ortak bir uygulama" olmadığını düşünüyorum, ama kesinlikle sicimin bir araya gelmesi yol değil. Davalarla başa çıkmak için kendi API'nizi geliştirebilirsiniz, ancak biraz çaba gerektirebilir. Özellikle, farklı platformlar konusunda dikkatli olmalısınız. Örneğin, Windows'ta \Unix tabanlı sistemlerde ayırıcı iken /ayırıcıdır.

Javascript kitaplıklarına aşina değilim, ancak eminim bu vakaları işleyebilecek kitaplıklar olmalı. Örneğin, Java'da platformdan bağımsız yol işlemleriyle uğraşmak için Yol API'sini kullanabilirsiniz .


3
Windows aslında /yol dosya adı sınırlayıcısı olarak desteklemektedir . Bunun için komut satırındaki tuhaflıklar gerekir, ancak dosya G / Ç API'leri eğik çizgi ile iyi çalışır.
Ruslan

en.wikipedia.org/wiki/… "Windows sistem API'si eğik çizgiyi kabul eder ve bu nedenle yukarıdaki Unix örneklerinin tümü çalışmalıdır. Ancak Windows'taki birçok uygulama eğik çizgiyi başka amaçlar için yorumluyor veya geçersiz bir karakter olarak kabul ediyor ve bu nedenle sizden talep ediyor ters eğik çizgi girmek için - özellikle cmd.exe kabuğu (genellikle bir terminal penceresinde çalıştığı için genellikle "terminal" olarak adlandırılır). "
Mooing Duck

0

Benim kişisel tercihim şudur:

var assets = "/images"

var sounds = assets+"/sounds"

Her zaman mutlak yolları kullanırım ( /images/...), hataya daha az eğilimli olur bana. Ayrıca kullanımı daha aptaldır, var sounds = assets+"/sounds"çünkü assetssonda eğik çizgi olsa ve sonuca varmış olsanız bile /images//sounds, yine de çözülür /images/sounds. Bu tek sorumluluk reddi, istek işleyicinize bağlı olduğudur. Apache iyi işliyor gibi görünüyor (en azından belirli sürümler / yapılandırmalar, bkz. Http://www.amazon.com//gp//site-directory//ref=nav_sad ). Başka bir yolla /imagessoundsbitmezsin, bu kadar aptal değil :) Çift eğik çizgi kontrolü ve onları temizleme seçeneği de var. Diğer yaklaşımla bir seçenek değil.


11
Bildiğim tüm bağlamlarda, bir eğik çizgiyle ( /) başlayan bir yol, göreceli bir yol değil mutlak bir yoldur. Yoksa sadece ilki dışındaki yollar için mi demek istedin?
Bart van Ingen Schenau

@BartvanIngenSchenau Sizinle tamamen aynı fikirdeyim ve yıllardır onları arıyorum, ancak bir ön uç geliştirici tarafından yazılan bir makaleyi her okuduğumda bunlara göreceli yollar olarak atıfta bulunuyorlar. Varsayım yapmak istemedim bu yüzden iki kötülüğü daha az seçtim ...? Şimdi biliyorum ki yanımda bazı insanlar var Cevabımı güncelleyeceğim :)
rpaskett

2
Web geliştiricileri /somewhereiçin göreli bir yoldur çünkü ana bilgisayarı içermez, bu nedenle tarayıcı onu geçerli sayfanın ana bilgisayarına göre arar. Web dünyasında http://here/somewheremutlak bir URI'dir ve buna göredir /somewhereelse. Dosya sistemi dünyasında, /somewheremutlak, kökten geliyor /ve "başka bir yerde" mevcut çalışma dizinine göre.
Rob

3
@RobY, rpaskett: kullanmasinizi RFC3986 (tanımlar URI'ler RFC), http://here/somewheremutlak bir yol olan bir tanım, bir /somewheremutlak yol ile göreli bir referans ve somewhere/elsebir göreli yolu ile göreli bir referanstır. Görünüşe göre, bu çevrelerde "göreceli yol" göreceli bir referansı belirtmek için kullanılır.
Bart van Ingen Schenau

1
@BartvanIngenSchenau: pencerelerde eğik çizgiyle başlayan bir yol göreceli bir yoldur ve CWD'ye göredir. en.wikipedia.org/wiki/…
Mooing Duck

0

Smalltalk'ta / yöntemini String olarak tanımlamak basittir; böylece şöyle çalışır:

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

İşte yöntemin basit bir uygulaması (daha iyi yapabilirsiniz):

/ 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

Not : Ayrıca gibi sınır durumlarda daha fazla dikkat etmek isteyebilirsiniz '' / '', 'x/' / ''uygun davranışı belirlemek amacıyla, vb.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.