Có một cách thông thường để kết hợp các chuỗi đường dẫn tập tin?


34

Trong một ví dụ:

var assets = "images/"

var sounds = assets+"sounds/"

Có phải thông thường hơn để đặt dấu gạch chéo ở mặt sau của đường dẫn tệp?

var assets = "/images"

var sounds = assets+"/sounds"

Có một phương pháp khác là một thực hành phổ biến tốt?


Java có các chuỗi tĩnh File.separator và File.pathSeparator mà âm thanh có liên quan. Bằng cách này, bạn an toàn trên tất cả các nền tảng
Evorlor

1
@Evorlor Bạn hiếm khi cần sử dụng File.separatormặc dù, FilePathAPI chấp nhận cả hai /và `\`.
kapex

2
Bạn có thể cho biết ngôn ngữ nào bạn đang sử dụng không? Có lẽ đáng để thêm thẻ tương ứng.
Christopher Creutzig

@ChristopherCreutzig Tôi đang sử dụng Java - mặc dù tôi đã hỏi liệu có bất kỳ quy ước thường được sử dụng nào để kết hợp các thư mục tệp trong chuỗi không. Rõ ràng có một vài quy tắc thường được chấp nhận và một số ý nghĩa thông thường có liên quan, nhưng nó thay đổi một chút từ ngôn ngữ sang ngôn ngữ.
iiridescent

1
Đối với những gì nó có giá trị, trong thế giới unix (và trong các url), nhiều dấu gạch chéo về phía trước giữa một đường được xử lý giống hệt nhau, do đó, sẽ không có gì xấu xảy ra nếu bạn nhầm lẫn với nhiều dấu gạch chéo. Đây là một phần của Đặc tả Unix đơn; xem câu trả lời này - unix.stackexchange.com/a/1919/21161
yoniLavi

Câu trả lời:


37

Gần như mọi ngôn ngữ lập trình chính đều có một thư viện để xử lý các dấu tách thư mục cho bạn. Bạn nên tận dụng chúng. Điều này sẽ đơn giản hóa mã của bạn và ngăn ngừa lỗi .

Theo kinh nghiệm của tôi, lý do thông thường để kết hợp các chuỗi như thế này là chúng đến từ các nguồn khác nhau. Đôi khi, đó là những phần khác nhau từ một tập tin cấu hình. Đôi khi, đó là sự kết hợp liên tục với một đối số chức năng. Trong mọi trường hợp, khi chúng đến từ các nguồn khác nhau, bạn phải xem xét một số trường hợp khác nhau có thể có liên quan đến dấu phân cách ở hai đầu được kết hợp:

  • Cả hai đầu có thể có một dấu phân cách: "images/""/sounds"
  • Chỉ một người có dấu phân cách: "images""/sounds"hoặc "images/""sounds"
  • Không có dấu phân cách: "images""sounds"

Thực tế mỗi phần đến từ một nguồn khác nhau có nghĩa là mỗi nguồn có thể có những ý tưởng riêng về những quy ước phải tuân theo, nếu có ai đó nghĩ gì về nó! Bất cứ điều gì đang gọi mã của bạn không cần phải lo lắng về điều này . Mã của bạn nên xử lý tất cả các trường hợp vì ai đó sẽ vi phạm quy ước của bạn . Điều này sẽ dẫn đến lãng phí thời gian điều tra nguyên nhân gây ra lỗi và khắc phục. Tôi đã có một vài lần khó chịu khi đồng nghiệp đưa ra giả định về cách các đường dẫn nên được định dạng trong tệp cấu hình, nghĩa là tôi phải đi tìm mã và tìm ra những gì họ đang mong đợi (hoặc sửa mã).

Hầu hết các ngôn ngữ chính cung cấp một phương pháp để làm điều này cho bạn, đã xử lý nhiều trường hợp:

Có một cảnh báo với những điều này. Một số trong số này dường như cho rằng một dấu tách thư mục hàng đầu trong đối số thứ hai đề cập đến một đường dẫn gốc và điều này có nghĩa là đối số đầu tiên phải được loại bỏ hoàn toàn. Tôi không biết tại sao điều này được coi là hữu ích; Đối với tôi, nó chỉ gây ra vấn đề. Tôi chưa bao giờ muốn kết hợp hai phần đường dẫn và kết thúc với phần đầu tiên bị loại bỏ. Đọc tài liệu cẩn thận cho các trường hợp đặc biệt, và nếu cần, hãy viết một trình bao bọc thực hiện những gì bạn muốn với những điều này thay vì xử lý đặc biệt của chúng.

Điều này cũng giúp nếu bạn có bất kỳ nhu cầu hỗ trợ các hệ điều hành khác nhau. Các lớp này hầu như có mặt khắp nơi để chọn phân cách chính xác. Các thư viện thường có cách bình thường hóa các đường dẫn để phù hợp với các quy ước của hệ điều hành.

Trong trường hợp ngôn ngữ lập trình của bạn không có thư viện sẵn có, bạn nên viết một phương thức xử lý tất cả các trường hợp này và sử dụng nó một cách tự do và xuyên suốt các dự án.

Điều này rơi vào danh mục "không đưa ra giả định" và "sử dụng các công cụ giúp bạn."


2
Path.Combine của .NET không bị hỏng. Chỉ không cho nó ăn dải phân cách. đảm bảo rằng bạn đọc tài liệu, nếu đối số thứ hai là đường dẫn gốc, nó có kết quả được xác định. Bạn có thể không thích nó nhưng điều đó không có nghĩa là nó bị hỏng.
Erno

4
Hãy chắc chắn rằng bạn đã đọc tài liệu để đảm bảo nó không cố quá thông minh. Tôi đã từng sử dụng một thư viện có thể kết hợp thành công C:\Documents and Settings\Adminvới my folder:document.txthệ thống * nix để sản xuất /home/admin/my folder/document.txt- một mẹo dễ thương, nhưng trong thế giới thực, các heuristic liên quan đến việc giới thiệu nhiều lỗi hơn họ đã sửa.
Đánh dấu

1
Ngoài ra, đối với Java, Paths.get()chỉ cần chuyển đổi một đơn Stringthành một Pathđối tượng. Để tham gia các đường dẫn, bạn sẽ sử dụng Path.resolve(), có thể đi theo đường khác Pathhoặc a String. Có các phương thức khác trong Pathlớp cho phép tiếp tục tham gia các đường dẫn theo nhiều cách khác nhau.
Kat

1
Thật tệ, có vẻ như tôi đã không đọc tài liệu Pathsrất tốt.
Kat

1
Trên PowerShell, một phương pháp thay thế cho phương thức .NET [System.IO.Path]::Combine("abc", "\def")có hành vi được mô tả, là lệnh ghép ngắn Join-Path "abc" "\def"đưa ra "abc\def".
Jeppe Stig Nielsen

38

Trong Java, câu trả lời sẽ là "không phải ở trên". Thực hành tốt nhất sẽ là lắp ráp tên đường bằng cách sử dụng java.io.Filelớp; ví dụ

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

Các Filelớp học cũng sẽ chăm sóc của tách tên đường dẫn nền tảng cụ thể.

Có một vấn đề riêng về việc tên đường dẫn của bạn có nên bắt đầu bằng dấu gạch chéo hay không. Nhưng đó là nhiều việc phải làm với sự đúng đắn hơn là thực hành tốt nhất. Tên đường dẫn bắt đầu bằng dấu gạch chéo có nghĩa là một tên khác với tên đường dẫn không !!


Không có hỗ trợ rõ ràng cho việc xử lý tên đường dẫn trong thư viện Javascript lõi (ECMA), nhưng (ít nhất) Node.js cung cấp hỗ trợ thông qua mô đun Đường dẫn.


4
Một cái gì đó tương tự cũng là trường hợp đối với các ngôn ngữ .Net Framework và bất kỳ ngôn ngữ nào khác cung cấp các lớp hệ thống tệp.
James Snell

3
Cảm ơn bạn! Đây dường như là câu trả lời hữu ích nhất, mặc dù ngôn ngữ cụ thể, các thư viện nên tồn tại cho các ngôn ngữ khác nói chung, như .NET và C ++;
iiridescent

3
Thực sự, bất kỳ mã nào không sử dụng thư viện nên bị từ chối trong đánh giá mã. Trong trường hợp hiếm hoi không có thư viện tồn tại, câu trả lời sẽ là tự viết một cái thay vì dán các chuỗi thô.
Gort Robot


Con trăn có os.path.join. PowerShell có join-path. Tôi sẽ thêm một cái gì đó vào câu trả lời này. Tôi đã thấy rằng nếu bạn cần các đường dẫn tệp thành nhiều phần, nó làm cho mã của bạn rất dễ hỏng nếu bạn đưa ra các giả định về bất kỳ trong số chúng có đường dẫn tệp ở những vị trí cụ thể. Sử dụng các lớp này không chỉ giúp cho tính di động, mà còn xử lý tất cả các trường hợp cạnh có thể (gạch chéo ở cả hai đầu được nối, chém chỉ ở một bên, không có dấu gạch chéo nào cả). Tính linh hoạt này là vô giá khi bạn bỏ đường dẫn tệp trong tệp cấu hình.
jpmc26

21

Lưu ý rằng trong .NET, bạn nên sử dụng phương thức Path.Combine.

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

Lý do cho điều này là vì nó 'biết' các ký tự chính xác sẽ được sử dụng khi xây dựng tên thư mục.

Điều này sẽ loại bỏ "vấn đề" sửa lỗi trước hoặc sau.


4
os.path.join về cơ bản cũng làm điều tương tự với trăn
StarWeaver

Lưu ý rằng path.combine không giúp bạn thoát khỏi công việc lo lắng về người
tách biệt

1
@jmoreno - Trong ví dụ của tôi KHÔNG có dải phân cách. Câu hỏi bạn liên kết đến có các dấu tách mã hóa cứng và nếu sai về cơ bản vì đường dẫn thứ hai là một đường dẫn tuyệt đối.
Erno

Hãy cẩn thận với điều này, mặc dù. Tôi không chắc chắn về .NET, nhưng os.path.join('src', '../../../your_secret_stuff') hợp lệ trong Python; nói cách khác, đừng mù quáng sử dụng các phương pháp này vào đầu vào của người dùng.
sapi

@sapi - Tất nhiên, đầu vào của người dùng phải luôn được vệ sinh nhưng đó là trách nhiệm của lập trình viên, không phải của API.
Erno

5

Khi xây dựng đường dẫn, tôi thường sử dụng một hàm thêm dấu gạch chéo nếu nó chưa có. Sau đó, các đường dẫn có thể được xây dựng như:

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

trong đó fs () thêm dấu gạch chéo nếu cần.


5

Các thư mục và tệp chỉ khác nhau ở một khía cạnh: các thư mục kết thúc bằng dấu gạch chéo trong đó các tệp không. Hơn nữa, các đường dẫn tuyệt đối bắt đầu bằng một /đường dẫn tương đối không. Nếu bạn sử dụng đường dẫn và tệp liên tục này cùng nhau thì sẽ không có vấn đề gì.

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

Nối hai đường dẫn tuyệt đối với nhau không có ý nghĩa gì, vì đường dẫn thứ hai nên liên quan đến đường dẫn thứ nhất. Kết hợp hai đường dẫn tương đối với nhau không có vấn đề gì, nhưng có thể dẫn đến hành vi không xác định nếu chương trình không biết đường dẫn tương đối có liên quan đến đâu.


Điều này có lẽ đã trả lời tốt nhất câu hỏi ban đầu của tôi, tôi nghĩ rằng tôi hiểu đường dẫn tệp tốt hơn, mặc dù như Stephen C và Erno đã nói, thư viện ngôn ngữ là đặt cược đầu tiên tốt nhất. Điều này giải thích quy ước tốt hơn mặc dù. Cảm ơn bạn!
iiridescent

Đường dẫn hệ thống tập tin hoặc URL?
MrWhite

1
Đối với tất cả ý định và mục đích, bạn cũng có thể áp dụng điều này trên uri. Một uri tuyệt đối sẽ bắt đầu với một giao thức, nhưng bên cạnh đó nó sẽ giống như tôi nghĩ.
Sumurai8

Không chắc làm thế nào đầu ra của bạn đang làm việc. Khi tôi làm điều đó tôi nhận được:var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
Damon

1
@Damon Tôi đã chỉnh sửa. absolutepathnên đã kết thúc bằng một dấu gạch chéo, bởi vì đó là một con đường. Bằng cách nào đó tôi đã bỏ qua điều đó khi tôi viết điều này.
Sumurai8

4

Tôi nghĩ rằng không có phép thuật hay "thông lệ chung" nào về cách thực hiện các đường dẫn, nhưng chắc chắn việc nối chuỗi không phải là hướng đi. Bạn có thể phát triển API của riêng mình để xử lý các trường hợp, nhưng nó có thể đòi hỏi một số nỗ lực. Đặc biệt, bạn nên cẩn thận về các nền tảng khác nhau. Ví dụ, trong Windows \là dải phân cách trong khi trong các hệ thống dựa trên Unix /là dải phân cách.

Tôi không quen thuộc với các thư viện Javascript, nhưng tôi chắc chắn nên có các thư viện để xử lý các trường hợp này. Ví dụ, trong Java, bạn có thể sử dụng API đường dẫn để xử lý các hoạt động đường dẫn độc lập với nền tảng.


3
Windows thực sự hỗ trợ /như dấu phân cách tên tệp đường dẫn. Điều này không cần quirks trong dòng lệnh, nhưng API I / O tệp hoạt động độc đáo với dấu gạch chéo về phía trước.
Ruslan

vi.wikipedia.org/wiki/, "API hệ thống Windows chấp nhận dấu gạch chéo, và do đó, tất cả các ví dụ Unix ở trên sẽ hoạt động. để nhập dấu gạch chéo ngược - đáng chú ý là shell cmd.exe (thường được gọi là "terminal" vì nó thường chạy trong cửa sổ terminal). "
Vịt Mooing

0

Sở thích cá nhân của tôi là thế này:

var assets = "/images"

var sounds = assets+"/sounds"

Tôi luôn luôn sử dụng các đường dẫn tuyệt đối ( /images/...), nó cảm thấy ít bị lỗi hơn, với tôi. Nó cũng là bằng chứng ngu ngốc hơn để sử dụng var sounds = assets+"/sounds"bởi vì ngay cả khi assetscó một dấu gạch chéo và bạn đã kết thúc /images//sounds, nó vẫn sẽ giải quyết /images/sounds. Một từ chối trách nhiệm là nó phụ thuộc vào xử lý yêu cầu của bạn. Apache dường như xử lý tốt (ít nhất là các phiên bản / cấu hình nhất định, xem http://www.amazon.com//gp//site-directory//ref=nav_sad ). Với cách khác mà bạn kết thúc /imagessounds, không phải là bằng chứng ngu ngốc :) Ngoài ra còn có tùy chọn kiểm tra các dấu gạch chéo kép và làm sạch chúng. Không phải là một lựa chọn với cách tiếp cận khác.


11
Trong tất cả các bối cảnh mà tôi biết, một đường dẫn bắt đầu bằng dấu gạch chéo ( /) là một đường dẫn tuyệt đối , không phải là đường dẫn tương đối. Hay bạn có nghĩa là nó chỉ dành cho các phần đường dẫn khác với phần đầu tiên?
Bart van Ingen Schenau

@BartvanIngenSchenau Tôi hoàn toàn đồng ý với bạn và tôi đã gọi họ như vậy trong nhiều năm, nhưng mỗi lần tôi đọc một bài viết được viết bởi một nhà phát triển front end, họ đều coi họ là những con đường tương đối. Tôi không muốn đưa ra các giả định vì vậy tôi đoán tôi đã chọn ít hơn hai tệ nạn ...? Bây giờ tôi biết tôi có một số người ở bên tôi sẽ cập nhật câu trả lời của tôi :)
rpaskett

2
Đối với các nhà phát triển web, /somewherelà một đường dẫn tương đối vì nó không bao gồm máy chủ lưu trữ, vì vậy trình duyệt sẽ tìm kiếm nó dựa trên máy chủ của trang hiện tại ... Trong thế giới web, http://here/somewherelà một URI tuyệt đối và /somewhereelsecó liên quan đến điều đó. Trong thế giới hệ thống tệp, /somewherelà tuyệt đối, đến từ root /và "cách nào đó" có liên quan đến thư mục làm việc hiện tại.
Cướp

3
@RobY, rpaskett: Đi theo RFC3986 (RFC xác định URI), http://here/somewherelà một URI có đường dẫn tuyệt đối, /somewherelà tham chiếu tương đối với đường dẫn tuyệt đối và somewhere/elselà tham chiếu tương đối với đường dẫn tương đối. Rõ ràng, trong các vòng tròn đó, "đường dẫn tương đối" được sử dụng để chỉ một tham chiếu tương đối.
Bart van Ingen Schenau

1
@BartvanIngenSchenau: trong các cửa sổ, một đường dẫn bắt đầu bằng dấu gạch chéo là một đường dẫn tương đối và có liên quan đến CWD. vi.wikipedia.org/wiki/ từ
Vịt Mooing

0

Trong Smalltalk, thật đơn giản để xác định phương thức / trong Chuỗi để nó hoạt động như thế này:

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

Đây là một cách thực hiện đơn giản của phương thức (bạn có thể làm cho nó tốt hơn):

/ 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

Lưu ý : bạn cũng có thể muốn chú ý hơn đến các trường hợp biên giới như '' / '', 'x/' / ''vv, để xác định hành vi thích hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.