Java StringBuilder를 파일로 버립니다
-
16-09-2019 - |
문제
StringBuilder를 텍스트 파일에 버리는 가장 효율적이고 우아한 방법은 무엇입니까?
넌 할 수있어:
outputStream.write(stringBuilder.toString().getBytes());
그러나 이것은 매우 긴 파일에 효율적입니까?
더 좋은 방법이 있습니까?
해결책
다른 사람들이 지적했듯이 작가를 사용하고 완충 작가를 사용하지만 전화하지 마십시오. writer.write(stringBuilder.toString());
대신 그냥 writer.append(stringBuilder);
.
편집 : 그러나 나는 당신이 하나의 라이너이기 때문에 다른 대답을 받아 들였다는 것을 알았습니다. 그러나 그 솔루션에는 두 가지 문제가 있습니다.
그것은 수락하지 않습니다
java.nio.Charset
. 나쁜. 항상 숯을 명시 적으로 지정해야합니다.여전히 당신이 고통을 겪게 만들고 있습니다
stringBuilder.toString()
. 단순성이 실제로 당신이 추구하는 것이라면 다음에서 다음을 시도하십시오. 구아바 프로젝트:
다른 팁
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();
}