2017-09-29 21 views
0

Java에서 파일에 텍스트를 쓸 때 BufferedWriter를 사용하고 있습니다. 그러나 생성자에서 사용자 지정 버퍼 크기를 제공하고 있습니다. 문제는, 내가 쓴 크기 (예를 들어, 버퍼 크기를 8KB로 지정하면 파일이 8KB로 한 번 기록됨)와 상관없이 파일에 씁니다. 그러나 Bufferedwriter 객체에 의해 점유 된 메모리 (YourKit 프로파일 러 사용)를 보면 실제로 주어진 버퍼 크기의 두 배 (이 경우 16KB)입니다.BufferedWriter 버퍼 크기 및 점유 메모리

내부 구현을 살펴보고 왜 이런 현상이 발생하는지 살펴 보았습니다. 주어진 크기의 문자 배열을 생성하고 있음을 알았습니다. 그리고 배열에 쓸 때 각 char이 2 바이트를 차지할 때 버퍼 크기의 두 배를 차지한다는 것은 의미가 있습니다.

내 질문은, 어떻게 버퍼링 된 16KB 버퍼에이 경우 8KB 만 쓰기 BufferedWriter 것입니다. 그리고 기술적으로 정확한가? 버퍼가 16KB이기 때문에 매번 8KB (반) 만 플러시하기 때문에.

답변

1

그러나 char 배열에 저장된 모든 문자가 버퍼 크기 (이 예에서는 16KB)에 도달하면 파일에 기록 될 것으로 예상됩니다.

8K 개의 문자가 16KB의 메모리를 차지합니다. 옳은.

이제 문자가 실제로 모두 ASCII 하위 집합에 있다고 가정합니다.

Java에서 출력 파일에 문자 스트림을 쓸 때 문자는 인코딩 스키마에 따라 바이트 스트림으로 인코딩됩니다.

ASCII 또는 Latin-1 ...과 같은 8 비트 문자 세트/인코딩 체계를 사용하여 8K의 문자를 인코딩 할 때 UTF- 8 (!!) ... 각 문자는 1 바이트로 인코딩됩니다. 따라서 을 포함하는 버퍼를 플러시하면 8K 문자가 8K 바이트 쓰기를 생성합니다.

+0

고마워요. @Stephen C. 지금 더 나은 통찰력을 얻었습니다. – Ravi

0

BufferedWriter의 크기는 문자 배열 크기입니다.

public BufferedWriter(Writer out, int sz) { 
    super(out); 
    if (sz <= 0) 
     throw new IllegalArgumentException("Buffer size <= 0"); 
    this.out = out; 
    cb = new char[sz]; 
    nChars = sz; 
    nextChar = 0; 

    lineSeparator = java.security.AccessController.doPrivileged(
     new sun.security.action.GetPropertyAction("line.separator")); 
} 

단일 문자가 단일 바이트와 같지 않습니다. 모두 문자 인코딩으로 정의됩니다.

따라서 위에서 설명한대로 정확하게 작업을 실행하려면 내부 버퍼가 바이트 수로 정확히 계산되는 BufferedOutputStream이라는 다른 클래스로 전환해야합니다.

public BufferedOutputStream(OutputStream out, int size) { 
    super(out); 
    if (size <= 0) { 
     throw new IllegalArgumentException("Buffer size <= 0"); 
    } 
    buf = new byte[size]; 
} 
+0

감사합니다. 알겠습니다. 단일 문자는 단일 바이트가 아닙니다. 그러나 char 배열에 저장된 모든 문자가 버퍼 크기에 도달하면 파일에 기록 될 것으로 예상됩니다 (char 배열이 16KB를 차지하기 때문에 16KB가됩니다). 그런데 왜 그런 일이 일어나지 않습니까? 왜 파일에 8KB 밖에 플러시하지 않았습니까? 이해 좀 도와주세요. – Ravi

+1

파일 인코딩에 따라 다릅니다. Java는 내부 문자 저장소로 _UTF-16_을 사용합니다. 즉, 각 문자에 대해 2 바이트를 사용하여 저장합니다. 그러나 문자가 ASCII이고 파일 인코딩이 _UTF-8_ 인 경우 모든 문자는 파일에서 1 바이트 만 사용하므로 결과입니다. – Alex

+0

@Alex와의 합의. https://stackoverflow.com/questions/7019504/in-what-encoding-is-a-java-char-stored-in을 참조하십시오.char 형의 내부 메모리 표현 2) bufferedWriter 내부의 char 버퍼 3) char to byte 변환 (바이트 자체의 내부 버퍼를 사용하는 경우도 있음) char 당 가변 바이트 수를 생성합니다. 이것은 복잡한 메모리 사용 예측을 보완합니다. 새도우 뷰는 char 버퍼 크기의 2 ~ 4 배가 적당합니다. 그러나 결국 8 개의 문자가 파일에 8 바이트를 기록하게됩니다. 또는 16. 또는 10 ... – GPI

0

이 파일에의 기입 해에 사용하는 인코딩에 따라 달라집니다 : ISO-8859-1 저장소는 단일 바이트로 문자, UTF-8은 단일 바이트 모든 ASCII 문자를 인코딩합니다.