나는 지금 얼마 동안 아래 관용구를 사용하고 있습니다. 그리고 그것은 내가 방문한 사이트에서 가장 널리 퍼진 것 같습니다.
Java에서 파일을 문자열로 읽는 더 좋고 다른 방법이 있습니까?
private String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
답변
파일에서 모든 텍스트를 읽습니다.
자바 11 추가 readString () 메서드를 작은 파일을으로 String
유지하면서 줄 종결 자로 보존했습니다.
String content = Files.readString(path, StandardCharsets.US_ASCII);
Java 7과 11 사이의 버전을 위해 다음은 유틸리티 방법으로 싸인 작고 강력한 관용구입니다.
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
파일에서 텍스트 줄 읽기
Java 7 은 파일을 텍스트 줄로 읽는 편리한 방법을 추가했습니다 .List<String>
. 이 방법은 줄 구분 기호가 각 줄의 끝에서 벗겨지기 때문에 “손실”됩니다.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 Files.lines()
은 Stream<String>
. 다시 말하지만,이 방법은 라인 구분 기호가 제거되어 손실됩니다. 이 경우 IOException
파일을 읽는 동안 발생, 그것은에 싸여 UncheckedIOException
있기 때문에,Stream
체크 된 예외를 던질 람다을 허용하지 않습니다.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
이것은 Stream
필요합니다close()
전화를; 이것은 API에 제대로 문서화되어 있지 않으며 많은 사람들이 메소드를 Stream
가지고 있지 않다고 생각 close()
합니다. 그림과 같이 ARM 블록을 사용해야합니다.
파일 이외의 소스로 작업하는 경우 lines()
BufferedReader
대신 방법을 .
메모리 활용
줄 바꿈을 유지하는 첫 번째 방법은 짧은 시간 동안 원시 파일 내용 (바이트 배열)과 디코딩 된 문자 (각각 인코딩 된 경우에도 16 비트 임)로 인해 파일 크기의 몇 배인 메모리를 일시적으로 요구할 수 있습니다. 파일에서 8 비트)는 한 번에 메모리에 상주합니다. 사용 가능한 메모리에 비해 작은 것으로 알고있는 파일에 적용하는 것이 가장 안전합니다.
디코딩을위한 입력 바이트 버퍼가 전체 파일을 포함 할 필요가 없기 때문에 라인을 읽는 두 번째 방법은 일반적으로 메모리 효율성이 높습니다. 그러나 여전히 사용 가능한 메모리에 비해 크기가 큰 파일에는 적합하지 않습니다.
큰 파일을 읽으려면 스트림에서 텍스트 청크를 읽고 처리 한 다음 다음으로 이동하여 동일한 고정 크기의 메모리 블록을 재사용하는 다른 디자인의 프로그램이 필요합니다. 여기서 “큰”은 컴퓨터 사양에 따라 다릅니다. 오늘날이 임계 값은 수 기가 바이트의 RAM 일 수 있습니다. Stream<String>
입력 “레코드”가 개별 라인 인 경우이를 사용하는 세 번째 방법 은이 방법 중 하나입니다. (의 readLine()
방법을 사용하는 것은이 방법과 BufferedReader
절차 상 동등합니다.)
문자 인코딩
원래 게시물의 샘플에서 누락 된 것은 문자 인코딩입니다. 플랫폼 기본값이 원하는 특수한 경우가 있지만 드물기 때문에 선택을 정당화 할 수 있어야합니다.
이 StandardCharsets
클래스는 모든 Java 런타임에 필요한 인코딩에 대한 상수를 정의합니다.
String content = readFile("test.txt", StandardCharsets.UTF_8);
플랫폼의 기본에서 사용할 수 클래스 자체 :Charset
String content = readFile("test.txt", Charset.defaultCharset());
참고 :이 답변은 Java 6 버전을 대체합니다. Java 7의 유틸리티는 코드를 안전하게 단순화하고 매핑 된 바이트 버퍼를 사용한 이전 답변은 매핑 된 버퍼가 가비지 수집 될 때까지 읽은 파일이 삭제되는 것을 방지했습니다. 이 답변의 “편집 된”링크를 통해 이전 버전을 볼 수 있습니다.
답변
외부 라이브러리를 사용하려면 Apache Commons IO (200KB JAR)를 확인하십시오. 여기 org.apache.commons.io.FileUtils.readFileToString()
에 전체를 읽을 수 있는 방법 이 포함되어 있습니다 File
.String
한 줄의 코드 .
예:
import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;
public String readFile() throws IOException {
File file = new File("data.txt");
return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}
답변
다음을 기반으로하는 매우 린 솔루션 Scanner
:
Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
또는 문자셋을 설정하려는 경우 :
Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
또는 try-with-resources 블록을 사용하여 다음을 요청 scanner.close()
합니다.
try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
String text = scanner.useDelimiter("\\A").next();
}
기억 Scanner
생성자가 던질 수 있습니다 IOException
. 그리고 수입하는 것을 잊지 마세요 java.io
및java.util
.
출처 : Pat Niemeyer의 블로그
답변
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);
Java 7부터는 이렇게 할 수 있습니다.
답변
타사 라이브러리를 포함하지 않는 대안 (예 : Commons I / O )을 찾고 있다면 Scanner 클래스를 사용할 수 있습니다 .
private String readFile(String pathname) throws IOException {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
try (Scanner scanner = new Scanner(file)) {
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + System.lineSeparator());
}
return fileContents.toString();
}
}
답변
구아바 에는 Willi aus Rohr가 언급 한 Commons IOUtils와 유사한 방법이 있습니다.
import com.google.common.base.Charsets;
import com.google.common.io.Files;
// ...
String text = Files.toString(new File(path), Charsets.UTF_8);
PiggyPiglet의 EDIT
Files#toString
은 더 이상 사용되지 않으며 Octobor 2019가 제거 될 예정입니다. 대신 사용
Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();
Oscar Reyes에 의해 편집
이것은 인용 라이브러리의 (간체 화 된) 기본 코드입니다.
InputStream in = new FileInputStream(file);
byte[] b = new byte[file.length()];
int len = b.length;
int total = 0;
while (total < len) {
int result = in.read(b, total, len - total);
if (result == -1) {
break;
}
total += result;
}
return new String( b , Charsets.UTF_8 );
편집 (Jonik 작성) : 위 내용이 최신 구아바 버전의 소스 코드와 일치하지 않습니다. 현재 소스 는 com.google.common.io 패키지의 Files , CharStreams , ByteSource 및 CharSource 클래스를 참조하십시오 .
답변
import java.nio.file.Files;
…….
String readFile(String filename) {
File f = new File(filename);
try {
byte[] bytes = Files.readAllBytes(f.toPath());
return new String(bytes,"UTF-8");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}