문제

StringBuilder를 텍스트 파일에 버리는 가장 효율적이고 우아한 방법은 무엇입니까?

넌 할 수있어:

outputStream.write(stringBuilder.toString().getBytes());

그러나 이것은 매우 긴 파일에 효율적입니까?

더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

다른 사람들이 지적했듯이 작가를 사용하고 완충 작가를 사용하지만 전화하지 마십시오. writer.write(stringBuilder.toString()); 대신 그냥 writer.append(stringBuilder);.

편집 : 그러나 나는 당신이 하나의 라이너이기 때문에 다른 대답을 받아 들였다는 것을 알았습니다. 그러나 그 솔루션에는 두 가지 문제가 있습니다.

  1. 그것은 수락하지 않습니다 java.nio.Charset. 나쁜. 항상 숯을 명시 적으로 지정해야합니다.

  2. 여전히 당신이 고통을 겪게 만들고 있습니다 stringBuilder.toString(). 단순성이 실제로 당신이 추구하는 것이라면 다음에서 다음을 시도하십시오. 구아바 프로젝트:

files.write (StringBuilder, file, charsets.utf_8)

다른 팁

BufferedWriter를 사용하여 쓰기를 최적화해야합니다 (OutputStream 대신 작성자를 사용하여 항상 문자 데이터를 작성하십시오). 캐릭터 데이터를 작성하지 않았다면 BufferedOutputStream을 사용합니다.

File file = new File("path/to/file.txt");
BufferedWriter writer = null;
try {
    writer = new BufferedWriter(new FileWriter(file));
    writer.write(stringBuilder.toString());
} finally {
    if (writer != null) writer.close();
}

또는 시도-이후 자원을 사용하여 (Java 7 이상)

File file = new File("path/to/file.txt");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
    writer.write(stringBuilder.toString());
}

궁극적으로 파일에 글을 쓰기 때문에 더 나은 접근 방식은 메모리에서 거대한 StringBuilder를 만들고 마지막에 모든 것을 작성하는 대신 버퍼링 라이터에게 더 자주 글을 쓰는 것입니다 (유용 사례에 따라 가능할 수도 있습니다. StringBuilder를 완전히 제거하려면). 처리 중에 점차적으로 쓰면 메모리를 저장하고 다른 스레드가 쓰기 시간에 디스크에서 많은 데이터를 읽으려고하지 않는 한 제한된 I/O 대역폭을 더 잘 활용할 수 있습니다.

글쎄, 문자열이 크다면 toString().getBytes() 중복 바이트 (2 또는 3 배)를 생성합니다. 문자열의 크기.

이를 피하기 위해 문자열 청크를 추출하여 별도의 부분으로 쓸 수 있습니다.

다음은 다음과 같습니다.

final StringBuilder aSB = ...;
final int    aLength = aSB.length();
final int    aChunk  = 1024;
final char[] aChars  = new char[aChunk];

for(int aPosStart = 0; aPosStart < aLength; aPosStart += aChunk) {
    final int aPosEnd = Math.min(aPosStart + aChunk, aLength);
    aSB.getChars(aPosStart, aPosEnd, aChars, 0);                 // 새 버퍼를 만들지 않습니다
    final CharArrayReader aCARead = new CharArrayReader(aChars); // 새 버퍼를 만들지 않습니다

    // 이것은 느릴 수 있지만 더 이상 버퍼를 생성하지 않습니다 (바이트의 경우)
    int aByte;
    while((aByte = aCARead.read()) != -1)
        outputStream.write(aByte);
}

도움이 되었기를 바랍니다.

당신은 사용할 수 있습니다 아파치 커먼즈 IO 당신에게 제공하는 도서관 파일:

FileUtils.writeStringToFile(file, stringBuilder.toString(), Charset.forName("UTF-8"))

문자 데이터를 위해 더 잘 사용합니다 Reader/Writer. 귀하의 경우 a BufferedWriter. 가능하면 사용하십시오 BufferedWriter 처음부터 대신 StringBuilder 메모리를 저장합니다.

비 아그를 부르는 방법에 주목하십시오 getBytes() 메소드는 플랫폼 기본 문자 인코딩을 사용하여 문자를 디코딩합니다. 플랫폼 기본 인코딩이 예를 들어 있으면 실패 할 수 있습니다. ISO-8859-1 문자열 데이터에는 외부의 문자가 포함되어 있습니다 ISO-8859-1 숯불. 더 잘 사용합니다 getBytes(charset) 당신이 다음과 같은 다음과 같이 직접 숯을 지정할 수 있습니다. UTF-8.

문자열 자체가 길다면, 당신은 확실히 tostring ()을 피해야합니다. 스트림에 쓰는 가장 효율적인 방법은 이와 같은 것이어야합니다.

OutputStreamWriter writer = new OutputStreamWriter(
        new BufferedOutputStream(outputStream), "utf-8");

for (int i = 0; i < sb.length(); i++) {
    writer.write(sb.charAt(i));
}

Java 8 이므로이 작업 만하면됩니다.

Files.write(Paths.get("/path/to/file/file_name.extension"), stringBuilder.toString().getBytes());

그렇게하기 위해 제 3 자 라이브러리가 필요하지 않습니다.

기반 https://stackoverflow.com/a/1677317/980442

사용하는이 기능을 만듭니다 OutputStreamWriter 그리고 write(), 이것은 메모리도 최적화 된 것입니다. StringBuilder.toString().

public static void stringBuilderToOutputStream(
        StringBuilder sb, OutputStream out, String charsetName, int buffer)
        throws IOException {
    char[] chars = new char[buffer];
    try (OutputStreamWriter writer = new OutputStreamWriter(out, charsetName)) {
        for (int aPosStart = 0; aPosStart < sb.length(); aPosStart += buffer) {
            buffer = Math.min(buffer, sb.length() - aPosStart);
            sb.getChars(aPosStart, aPosStart + buffer, chars, 0);
            writer.write(chars, 0, buffer);
        }
    }
}

대부분의 답변에 대한 벤치 마크 + 개선 된 구현 : https://www.genuitec.com/dump-a-stringbuilder-to-file/

최종 구현은 라인을 따라 있습니다

try {
    BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(
                    new FileOutputStream(file, append), charset), BUFFER_SIZE);
    try {
        final int length = sb.length();
        final char[] chars = new char[BUFFER_SIZE];
        int idxEnd;
        for ( int idxStart=0; idxStart<length; idxStart=idxEnd ) {
            idxEnd = Math.min(idxStart + BUFFER_SIZE, length);
            sb.getChars(idxStart, idxEnd, chars, 0);
            bw.write(chars, 0, idxEnd - idxStart);
        }
        bw.flush();
    } finally {
        bw.close();
    }
} catch ( IOException ex ) {
    ex.printStackTrace();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top