File.separator와 경로의 슬래시의 차이점


200

Java Path-String에서 사용 File.separator과 일반 의 차이점은 무엇입니까 /?

이중 백 슬래시 \\플랫폼 독립성 과 달리 두 버전 모두 Windows 및 Unix에서 작동하기 때문에 이유가 아닌 것 같습니다.

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
@ 링 '역사적 이유'와 같은 무엇?
Lorne의 후작

답변:


246

파일 처리를위한 Java 라이브러리를 사용하면 /모든 플랫폼에서 안전하게 백 슬래시가 아닌 슬래시를 사용할 수 있습니다. 라이브러리 코드는 사물을 내부적으로 플랫폼 별 경로로 변환하는 것을 처리합니다.

File.separator그러나 UI 에 사용 하는 것이 좋습니다. Java에 의미가있는 것보다는 OS에 의미가있는 것을 사람들에게 보여주는 것이 가장 좋습니다.

업데이트 : 5 분 동안 검색하면 "항상 슬래시를 사용할 수 있습니다"동작을 찾을 수 없었습니다. 지금, 나는 확실히 나는 그것을 문서화 본 적이 있어요,하지만 (내 기억이 완벽하지 않기 때문에) 공식 참조를 찾는 누락됩니다에, 나는 사용하여 다루고 싶어요 File.separator당신이 있기 때문에 알고 그 뜻을 작업.


2
런타임에 구분 기호가 다른 것으로 변환되기를 기대하기 때문에 성능에 문제가있을 수도 있습니다. 또한 지원되지 않는 모든 JVM에서이 문제가 발생할 것으로 예상하지 마십시오.
jpabluz

7
@TJ Crowder : "5 분 동안 검색하면 '항상 슬래시를 사용할 수 있습니다'동작을 찾을 수 없었습니다." JVM의 기능이 아니며 Windows NT API의 기능입니다.
Powerlord

12
@Powerlord : Windows가 Windows를 수행하는 경우 훌륭하지만 라이브러리 (JVM이 아닌)도 수행합니다. 특히, 공용 API를 통해 수신 된 경로와 파일 경로 문자열 (예 :)을 다루는 거의 모든 것이 덮개 아래에서 사용 되는 경로를 "정규화"하기 File위해 FileSystem.normalize모든 곳에서 FileWriter(String)사용 File됩니다.
TJ Crowder

9
Java7부터는 File.separator를 더 이상 사용할 필요가 없습니다. dir에서 dir로, dir에서 파일 이름 결합에 java.nio.file.Paths (Paths.get (first, more ...))를 사용하는 것이 훨씬 간단하고 깔끔합니다.
magiccrafter

6
@jpabluz '성능 문제'! 진심 이세요? 용도 파일 이름을 디스크에 넣는 것을 고려할 때 변환의 런타임 영향은 전혀 중요하지 않습니다. 의 사양의 일부이므로 모든 JVM에서 지원해야합니다 File.
Lorne의 후작

316

당신은 사용 File.separator언젠가는 당신의 프로그램이 개발 플랫폼에서 실행할 수 있기 때문에 먼 땅, 말 울음 소리와 소는 모든 엘리베이터를 운영 이상한 일들과 낯선 사람들의 땅. 이 땅에서 사람들은 전통적으로 ":"문자를 파일 구분 기호로 사용 했으므로 JVM은 자신의 소원에 따라야합니다.


4
그래, 뾰족한 정말 엘보 니아에서 우리를 tooks (그는 더 뾰족한 헤어 스타일 ;-) (괴짜 말장난의 내부)이없는 희망
Riduidel

4
"... 소는 모든 엘리베이터를 운행합니다." 마찬가지로 나는 그것을 읽을 때 커피 한 모금을 마시지 않았습니다. 훌륭한.
TJ Crowder

8
이러한 국가에서는 편의를 위해이 모든 크랙을 포함하는 새로운 org.apache.chicken.elevators.OperatorUtility 클래스를 사용합니다.
Brain

27

File.separator를 사용하여 파일 이름을 참조하는 것은 과도하지만 (먼 곳을 상상하는 사람들에게는 JVM 구현이 Windows가 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
public abstract String fromURIPath (String path)
필요한 경우 지정된 URI 경로 문자열을 사후 처리합니다. 예를 들어, "/ c : / foo"를 "c : / foo"로 변환하기 위해 win32에서 사용됩니다. 경로 문자열에는 여전히 슬래시 구분 기호가 있습니다. File 클래스의 코드는이 메소드가 리턴 된 후이를 변환합니다.

이것은 FileSystem.fromURIPath()Windows에서만 URI 경로에 대한 포스트 처리를 수행 한다는 것을 의미 하며 다음 줄에 있기 때문입니다.

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

각 '/'를 시스템 종속으로 대체 seperatorChar하므로 항상 모든 OS 에서 '/'가 안전하다는 것을 확신 할 수 있습니다 .


8

글쎄, Unix와 Windows (Portable devices 등)보다 많은 OS가 있으며 Java는 이식성으로 유명합니다. 모범 사례는이를 사용하는 것이므로 JVM이 해당 OS에 가장 적합한 것을 결정할 수 있습니다.


이러한 OS의 대부분은 UNIX의 일부 변형을 실행합니다. 오래된 Mac 스타일 :구분 기호는 오랫동안 사라졌습니다. Windows를 제외한 모든 사람들이 /더 이상 표준을 사용하는 것 같습니다 . 그리고 심지어 창문조차도 슬래시를 잘 처리하는 것 같습니다. cd /windows/system기본 시스템 드라이브에서 Windows 10 시스템을 사용해보십시오 . 사용자를 혼동하지 않기 위해 시스템 구분 기호를 사용하여 경로를 계속 표시하려는 경우 /다른 곳에서는 슬래시를 사용 하고 배포 할 가능성이있는 모든 위치에서 코드가 작동한다고 확신 할 수 있습니다.
Shadow Man

7

그것은 도중에 큰 차이를 만들지 않지만 돌아 오는 길에 있습니다.

새 File (String path)에서 '/'또는 '\'를 사용할 수 있지만 File.getPath ()는 그중 하나만 제공합니다.


약간의 보정 ...에서 윈도우 당신도 앞으로 사용할 수 있습니다 /또는 뒤로 \\ 슬래시. 그러나 다른 곳에서는 슬래시를 사용하는 것이 좋습니다. 그렇지 않으면 /문제가 발생합니다.
Shadow Man

6

파티에 늦었다. JDK 1.8 및 Eclipse MARS 1이 설치된 Windows 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)이 있습니다.
Stephan

9
그것은 질문과 다른 시나리오입니다. ClassLoader의 getResourceAsStream 메소드는 파일 경로를 사용하지 않지만 파일 시스템에 있거나 없을 수 있는 자원 이름 을 자원 경로 분리 자로 '/'만 허용하는 것으로 문서화 됩니다.
daiscog

@Stephan은 File.separator백 슬래시 이기 때문에 재미있는 탈출구가 없습니다 . 백 슬래시를 이스케이프해야하는 이스케이프 문자로 처리되는 하드 코딩 된 문자열에만 있습니다. 당신은 텍스트 파일에 문자를 저장, 또는에서 한 경우 char또는 String당신은 이미 예상 된 백 슬래시 문자로 변환 된 것 같이 그것을 2 시간을 탈출 할 필요가 없습니다. 이것을 직접보십시오 :String backslash = "\\"; System.out.println("welcome" + backslash + "to" + backslash + "reality");
Shadow Man

2
@Stephan 오, 알 겠어요 ... 당신은 세번째 줄에 대해 이야기하고 있었어요. 당신이 올바른지. 해당 줄 (하드 코드 된 문자열)에서 이스케이프 문자를 이스케이프해야합니다. 내 눈은 두 번째 줄에서 멈 췄고 처음에는 세 번째 줄조차 보지 못했습니다.
Shadow Man

3

휴대가 간편하고 단순합니다.


예, 이식성을 위해 백 슬래시를 사용 하지 마십시오 . 슬래시 /또는 시스템 분리기를 사용하십시오 File.separator. 둘 다 어디서나 작동하는 것 같습니다. File.separator모든 곳에서 작동 하는 것이 보장 되지만 간단한 슬래시 /도 모든 곳에서 작동하는 것으로 보입니다. 어딘가에서 작동하지 않으면 그것에 대해 듣고 싶습니다. 모든 시스템에서 작동한다고 생각합니다. 적어도, 나는 여전히 /작동하지 않는 곳을 찾지 못했습니다 (Mac OSX, Windows, * nix, Android, iOS- ":"를 구분 기호로 사용하는 이전 OSX Mac은 확인하지 않았습니다. OS / 2, NeXT 또는 다른 고대 OS 중 하나).
Shadow Man

1

"프로그래머 용 Java SE8"은 Java 가 어느 쪽에도 대처할 것이라고 주장 합니다. (pp. 480, 마지막 단락). 이 예는 다음과 같이 주장합니다.

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

잘 파싱합니다. 마지막 (유닉스 스타일) 구분 기호를 기록해 두십시오.

그것은 끈적 거리며 아마도 오류가 발생하기 쉽지만 그것이 (Deitel과 Deitel) 주장입니다.

Java보다는 사람들에 대한 혼란이이 기능을 사용하지 않는 이유라고 생각합니다.


1

신사들이 변형 세부 사항과의 차이점을 설명했습니다.

여러 OS에 배포 할 수있는 프로그램에서 파일을 처리 할 때 Apache Commons io api, 클래스를 사용하는 것이 좋습니다 FilenameUtils.


0

파일 또는 디렉토리의 경로 이름은 호스트 시스템의 이름 지정 규칙을 사용하여 지정됩니다. 그러나 File 클래스는 플랫폼 독립적 인 방식으로 파일 및 디렉토리 이름을 처리하는 데 사용할 수있는 플랫폼 종속 상수를 정의합니다.

Files.seperator는 경로 이름에서 디렉토리와 파일 구성 요소를 구분하는 문자 또는 문자열을 정의합니다. 이 구분 기호는 각각 Unix, Windows 및 Macintosh의 경우 '/', '\'또는 ':'입니다.


Macintosh의 ":"은 고대입니다. OSX 이후로, Mac은 "/"(슬래시)도 사용합니다. "/"(슬래시)는 표준 UNIX 파일 시스템과 함께 UNIX 형식으로 실행되기 때문입니다.
Shadow Man


0

Ubuntu는 File.separator를 사용하여 디렉토리 대신 이름에 "\"로 파일을 생성했습니다. 어쩌면 나는 파일 (및 디렉토리)을 만드는 방법에 게으르고 피할 수 있었지만, 항상 "/"를 사용하여 이름에 "\"가있는 파일을 피하십시오.


0

Linux 구분 기호를 사용하여 준비 경로 (예 : 데이터베이스에 저장)에서 파일을 만들려고하면 어떻게해야합니까?

어쩌면 경로를 사용하여 파일을 만드십시오.

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

그러나 Windows는 다른 구분 기호 ( \)를 사용합니다 . 슬래시 구분 기호를 플랫폼 독립적으로 변환 할 수 있습니까? 처럼:

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

이 방법은 convertPathToPlatformIndependent아마도 "/"로 분리되어 File.separator와 결합 될 것입니다.

글쎄, 그것은 플랫폼 독립적 인 언어 (좋아?)와 Java가 이미 Windows 또는 Linux에서 의 사용을 지원하는 언어 에는 좋지 않습니다/ . 그러나 경로로 작업하고 매번이 변환을 기억 해야하는 경우 이것은 악몽이 될 것이며 미래에는 응용 프로그램에 대한 실질적인 이익을 얻지 못할 것입니다 (@Pointy가 설명 한 우주에서).

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