파일 경로 문자열을 결합하는 일반적인 방법이 있습니까?


34

예를 들면 다음과 같습니다.

var assets = "images/"

var sounds = assets+"sounds/"

파일 경로 뒤에 슬래시를 두는 것이 더 일반적인 방법입니까?

var assets = "/images"

var sounds = assets+"/sounds"

좋은 일반적인 방법이 또 있습니까?


Java에는 정적 문자열 File.separator 및 File.pathSeparator가 있습니다. 이렇게하면 모든 플랫폼에서 안전합니다
Evorlor

1
@Evorlor 당신은 거의 사용할 필요가 없으며 File.separator, Fileand PathAPI는 /`와` 를 모두 받아들 입니다.
kapex

2
사용중인 언어를 알려주시겠습니까? 해당 태그를 추가하는 것이 좋습니다.
Christopher Creutzig 2016 년

@ChristopherCreutzig Java를 사용하고 있습니다-파일 디렉토리를 문자열로 결합하는 데 일반적으로 사용되는 규칙이 있는지 묻고있었습니다. 분명히 일반적으로 받아 들여지는 규칙이 몇 가지 있으며 상식이 있지만 언어마다 조금씩 다릅니다.
iiridescent

1
유닉스 세계 (및 URL)에서 가치가있는 경로의 중간에 여러 개의 슬래시가 단일 경로와 동일하게 취급되므로 더 많은 슬래시 측면에서 잘못하면 아무 일도 일어나지 않습니다. 단일 유닉스 사양의 일부입니다. 이 답변 참조 -unix.stackexchange.com/a/1919/21161
yoniLavi

답변:


37

거의 모든 주요 프로그래밍 언어에는 디렉토리 구분 기호를 처리하는 라이브러리가 있습니다. 당신은 그들을 활용해야합니다. 이것은 코드를 단순화하고 버그를 예방합니다 .

필자의 경험에 따르면 이와 같은 문자열을 결합하는 일반적인 이유는 다른 소스에서 온 것입니다. 때로는 구성 파일과 다른 부분입니다. 때로는 함수 인수와 상수 결합입니다. 어떤 경우이든, 서로 다른 출처에서 나온 경우 끝 부분의 구분 기호를 결합 할 수있는 여러 가지 가능한 경우를 고려해야합니다.

  • 양단 구분을 할 수 : "images/""/sounds"
  • 오직 하나의 세퍼레이터를 가지고를 "images"하고 "/sounds"또는 "images/""sounds"
  • 둘 세퍼레이터가 없다 : "images""sounds"

각 부분이 다른 출처에서 나왔다는 사실은 누군가가 그것에 대해 전혀 생각하지 않았다면 각 출처가 따라야 할 규칙에 대한 자체 아이디어를 가질 수 있음을 의미합니다! 코드를 호출하는 것이 무엇이든 이것에 대해 걱정할 필요는 없습니다 . 누군가 귀하의 협약을 위반할 것이기 때문에 귀하의 코드는 모든 경우를 처리해야 합니다 . 이로 인해 오류의 원인을 조사하고 수정하는 데 시간이 낭비됩니다. 동료가 구성 파일에서 경로의 형식을 지정하는 방법에 대해 가정했을 때 몇 가지 불쾌한 경우가있었습니다. 즉, 코드를 찾아서 예상했던 것을 파악해야합니다 (또는 코드 수정).

대부분의 주요 언어는 이미 많은 경우를 처리하는 방법을 제공합니다.

이것들에 대한 경고가 있습니다. 이들 중 다수는 두 번째 인수에서 선행 디렉토리 구분 기호가 루트 경로를 참조하고 첫 번째 인수가 완전히 삭제되어야 함을 가정 한 것으로 보입니다. 이것이 왜 유용한 지 모르겠습니다. 나를 위해, 그것은 단지 문제를 일으킨다. 나는 두 개의 경로 부분을 결합하고 첫 번째 부분이 떨어지는 것을 끝내고 싶지 않았습니다. 특수한 경우 문서를주의 깊게 읽고 필요한 경우 특수 처리 대신 원하는 작업을 수행하는 래퍼를 작성하십시오.

다른 운영 체제를 지원해야 할 경우에도 도움이됩니다. 이 클래스는 거의 모든 곳에서 올바른 구분 기호를 선택합니다. 라이브러리에는 일반적으로 OS 규칙에 맞게 경로를 표준화하는 방법이 있습니다.

프로그래밍 언어에 쉽게 사용할 수있는 라이브러리가없는 경우 이러한 모든 경우를 처리하고 프로젝트 전체에서 자유롭게 사용할 수 있는 방법을 작성 해야 합니다.

이는 "가정을 만들지 않음"과 "도움이되는 도구 사용"범주에 속합니다.


2
.NET의 Path.Combine이 손상되지 않았습니다. 분리기를 공급하지 마십시오. 두 번째 인수가 루트 경로 인 경우 문서를 읽고 결과가 정의되어 있는지 확인하십시오. 당신이 그것을 좋아하지 않을 수도 있지만 그것이 고장났다는 것을 의미하지는 않습니다.
Erno

4
너무 영리하지 않도록 설명서를 읽으십시오. 한때 * nix 시스템 C:\Documents and Settings\Admin과 성공적으로 결합 할 수있는 라이브러리를 사용하여 귀여운 트릭을 만들었습니다. 그러나 실제로는 휴리스틱이 수정 한 것보다 더 많은 버그를 도입했습니다. my folder:document.txt/home/admin/my folder/document.txt
Mark

1
또한 Java의 Paths.get()경우 단일 StringPath객체 로 변환 합니다. 경로를 결합하려면을 사용합니다.이 경로 Path.resolve()는 다른 경로 Path또는 을 사용할 수 있습니다 String. Path클래스에는 다양한 방법으로 경로를 더 조인 할 수 있는 다른 메소드가 있습니다 .
Kat

1
내 나쁜, 내가 문서를 Paths잘 읽지 않은 것 같습니다 .
Kat

1
PowerShell [System.IO.Path]::Combine("abc", "\def")에서 설명 된 동작이있는 .NET 메서드의 대안 Join-Path "abc" "\def""abc\def".
Jeppe Stig Nielsen

38

자바에서 답은 "위의 어느 것도 아니다". 모범 사례는 java.io.File클래스를 사용하여 경로 이름을 어셈블하는 것입니다 . 예 :

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

File클래스는 플랫폼 별 경로 이름 구분 기호도 처리합니다.

경로 이름이 슬래시로 시작해야하는지 여부에 대한 별도의 문제가 있습니다. 그러나 그것은 모범 사례보다 정확성과 관련이 있습니다. 슬래시로 시작 하는 경로 이름은 그렇지 않은 경로 이름 과 다른 것을 의미합니다 !!


ECMA (핵심) Javascript 라이브러리에는 명시 적으로 경로 이름 처리가 지원되지 않지만 Node.js는 Path 모듈을 통해 지원을 제공합니다.


4
.Net Framework 언어 및 파일 시스템 클래스를 제공하는 다른 언어의 경우도 마찬가지입니다.
James Snell

3
고맙습니다! 이것은 언어에 따라 다르지만 .NET 및 C ++와 같은 다른 언어의 라이브러리는 일반적으로 존재해야합니다.
iiridescent

3
실제로 라이브러리를 사용하지 않는 코드는 코드 검토에서 거부되어야합니다. 드문 경우이지만 라이브러리가 존재하지 않는 경우에는 원시 문자열을 붙여 넣기보다는 직접 작성하는 것이 좋습니다.
로봇 고트


파이썬은 os.path.join. PowerShell에는 join-path. 이 답변에 무언가를 추가 할 것입니다. 여러 부분으로 파일 경로가 필요한 경우 특정 위치에 파일 경로가있는 파일에 대해 가정하면 코드가 매우 취약 하다는 것을 알았 습니다. 이러한 클래스를 사용하면 이식성에 도움이 될뿐만 아니라 가능한 모든 경우를 처리합니다 (양단의 슬래시, 한쪽 만 슬래시, 슬래시 없음). 구성 파일에서 파일 경로를 삭제하면 이 유연성이 매우 중요 합니다.
jpmc26

21

.NET에서는 Path.Combine 메서드를 사용해야합니다.

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

폴더 이름을 구성 할 때 사용할 올바른 문자 를 '알기' 때문 입니다.

이것은 사전 또는 사후 수정의 '문제'를 제거합니다.


4
os.path.join은 기본적으로 파이썬에서도 똑같은 일을합니다
StarWeaver

path.combine은 seperator에 대해 걱정할 필요가 없습니다 : stackoverflow.com/questions/53102/…
jmoreno

1
@jmoreno-내 예제에는 구분 기호가 없습니다. 연결 한 질문에는 하드 코드 된 구분 기호가 있으며 두 번째 경로가 절대 경로이기 때문에 근본적으로 잘못되었습니다.
Erno

그래도 조심하십시오. .NET에 대해 잘 모르겠지만 Python os.path.join('src', '../../../your_secret_stuff') 에서는 유효합니다. 다시 말해, 사용자 입력에이 방법을 맹목적으로 사용하지 마십시오.
sapi

@sapi-물론 사용자 입력은 항상 위생 처리되어야하지만 API가 아닌 프로그래머의 책임입니다.
Erno

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

두 개의 절대 경로를 함께 연결하면 두 번째 경로가 첫 번째 경로에 상대적이어야하므로 의미가 없습니다. 두 상대 경로를 함께 연결해도 문제는 없지만 프로그램이 상대 경로의 상대 위치를 모르는 경우 동작이 정의되지 않을 수 있습니다.


이것은 아마도 내 원래의 질문에 가장 잘 대답했을 것입니다. 파일 경로를 더 잘 이해한다고 생각합니다 .Stephen C와 Erno가 말했듯이 언어 라이브러리가 가장 좋은 방법입니다. 이것은 컨벤션을 더 잘 설명합니다. 고맙습니다!
iiridescent

파일 시스템 경로 또는 URL?
MrWhite

1
모든 의도와 목적을 위해이를 URI에 적용 할 수 있습니다. 절대 URI는 프로토콜로 시작하지만 그 외에는 제 생각과 동일합니다.
Sumurai8

출력이 어떻게 작동하는지 잘 모르겠습니다. 내가 할 때 :var a = "/my/path" + "css/" + "test.css"; //Output: "/my/pathcss/test.css"
데이먼

1
@Damon 나는 편집했다. absolutepath경로이기 때문에 슬래시로 끝나야합니다. 어떻게 든 나는 이것을 쓸 때 그것을 간과했습니다.
Sumurai8

4

나는 경로를 구현하는 방법에 대한 마술이나 "공통 관행"이 없다고 생각하지만 문자열 연결은 갈 길이 아닙니다. 사례를 처리하기 위해 자체 API를 개발할 수 있지만 약간의 노력이 필요할 수 있습니다. 특히, 다른 플랫폼에주의해야합니다. 예를 들어 Windows \에서는 구분 기호가 있고 Unix 기반 시스템 /에서는 구분 기호입니다.

Javascript 라이브러리에 익숙하지 않지만 이러한 경우를 처리하기위한 라이브러리가 있어야합니다. 예를 들어 Java에서는 Path API를 사용하여 플랫폼 독립적 인 경로 작업을 처리 할 수 있습니다 .


3
Windows는 실제로 /경로 파일 이름 구분 기호로 지원 합니다. 이것은 명령 행에 문제가 필요하지만 파일 I / O API는 슬래시와 잘 작동합니다.
Ruslan

en.wikipedia.org/wiki / ... "Windows 시스템 API는 슬래시를 허용하므로 위의 모든 Unix 예제가 작동해야합니다. 그러나 Windows의 많은 응용 프로그램은 다른 목적으로 슬래시를 해석하거나 유효하지 않은 문자로 취급하므로 사용자에게 필요합니다. 백 슬래시 (특히 cmd.exe 셸 (일반적으로 터미널 창에서 실행되는 "터미널"이라고 함))를 입력합니다. "
Mooing Duck

0

내 개인적인 취향은 다음과 같습니다.

var assets = "/images"

var sounds = assets+"/sounds"

나는 항상 절대 경로 ( /images/...)를 사용 하며 오류가 덜 발생합니다. 후행 슬래시가 있고으로 끝나 더라도 여전히 해결 var sounds = assets+"/sounds"되기 때문에 사용하는 것이 더 어리석은 증거 입니다. 한 가지 면책 조항은 요청 핸들러에 따라 다릅니다. 아파치는 잘 처리하는 것 같습니다 (적어도 특정 버전 / 구성, http://www.amazon.com//gp//site-directory//ref=nav_sad 참조 ). 다른 방법으로 당신은 그렇게 바보 증거로 끝나지 않을 것입니다 :) 이중 슬래시를 확인하고 정리하는 옵션도 있습니다. 다른 접근 방식에는 옵션이 없습니다.assets/images//sounds/images/sounds/imagessounds


11
내가 아는 모든 상황에서 슬래시 ( /)로 시작하는 경로 는 상대 경로 가 아니라 절대 경로입니다. 아니면 첫 번째 경로 이외의 경로 섹션에만 해당합니까?
Bart van Ingen Schenau

@BartvanIngenSchenau 나는 당신에게 전적으로 동의하며 몇 년 동안 그들에게 전화 해 왔지만, 프론트 엔드 개발자가 작성한 기사를 읽을 때마다 그것들을 상대 경로라고합니다. 나는 가정을하고 싶지 않아서 두 가지 악을 덜 골랐다. 이제 나는 내 편에 사람들이 있다는 것을 알고있다. 나는 나의 대답을 업데이트 할 것이다 :)
rpaskett

2
웹 개발자에게는 /somewhere호스트가 포함되어 있지 않기 때문에 상대 경로입니다. 따라서 브라우저는 현재 페이지의 호스트를 기반으로 검색합니다. 웹 세계에서는 http://here/somewhere절대 URI /somewhereelse이며 이에 상대적입니다. 파일 시스템 세계에서는 /somewhereroot /에서 오는 절대적 이며 "somewhereelse"는 현재 작업 디렉토리와 관련이 있습니다.
Rob

3
@RobY, rpaskett : RFC3986으로 가기 (URI를 정의하는 RFC) http://here/somewhere는 절대 경로가있는 URI이며 절대 경로 /somewhere가있는 상대 참조이며 상대 경로 somewhere/else가있는 상대 참조입니다. 분명히,이 원에서 "상대 경로"는 상대 참조를 나타내는 데 사용됩니다.
Bart van Ingen Schenau

1
@BartvanIngenSchenau : 창에서 슬래시로 시작하는 경로는 상대 경로이며 CWD를 기준으로합니다. en.wikipedia.org/wiki/…
Mooing Duck

0

스몰 토크에서는 다음과 같이 작동하도록 String에서 / 메소드를 정의하는 것이 간단합니다.

'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/' / ''적절한 행동을 결정하기 위해, 등.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.