큰 파일 (예 : 2GB)에서 마지막 n 줄을 읽어야합니다. 파일은 UTF-8로 인코딩됩니다.Java의 RandomAccessFile이 메모리의 전체 파일을 읽습니까?
가장 효율적인 방법을 알고 싶습니다. Java의 RandomAccessFile에 대해 읽으십시오. 그러나 seek() 메소드는 메모리에있는 전체 파일을 읽습니다. 네이티브 구현을 사용하므로 소스 코드를 참조 할 수 없었습니다.
큰 파일 (예 : 2GB)에서 마지막 n 줄을 읽어야합니다. 파일은 UTF-8로 인코딩됩니다.Java의 RandomAccessFile이 메모리의 전체 파일을 읽습니까?
가장 효율적인 방법을 알고 싶습니다. Java의 RandomAccessFile에 대해 읽으십시오. 그러나 seek() 메소드는 메모리에있는 전체 파일을 읽습니다. 네이티브 구현을 사용하므로 소스 코드를 참조 할 수 없었습니다.
1) RandomAccessFile.seek는 파일 포인터의 현재 위치 만 설정하고 바이트는 메모리에 읽지 않습니다.
2) 파일이 UTF-8로 인코딩되었으므로이 파일은 텍스트 파일입니다. 우리가 일반적으로 BufferedReader를 사용하는 텍스트 파일을 읽기 위해 Java 7은 File.newBufferedReader를 추가하여 파일에서 텍스트를 읽는 BufferedReader의 인스턴스를 만들었습니다. 마지막 n 라인을 읽는 것은 비효율적 일 수도 있지만 구현하기 쉽습니다.
3) 효율적이기 위해서는 RandomAccessFile이 필요하고 끝에서부터 파일을 거꾸로 읽어야합니다. 여기 LF 그것은 바이트를 반전하는 라인을 작성 도달하면, 기본적인 예
public static void main(String[] args) throws Exception {
int n = 3;
List<String> lines = new ArrayList<>();
try (RandomAccessFile f = new RandomAccessFile("test", "r")) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
for (long length = f.length(), p = length - 1; p > 0 && lines.size() < n; p--) {
f.seek(p);
int b = f.read();
if (b == 10) {
if (p < length - 1) {
lines.add(0, getLine(bout));
bout.reset();
}
} else if (b != 13) {
bout.write(b);
}
}
}
System.out.println(lines);
}
static String getLine(ByteArrayOutputStream bout) {
byte[] a = bout.toByteArray();
// reverse bytes
for (int i = 0, j = a.length - 1; j > i; i++, j--) {
byte tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
return new String(a);
}
그것은 꼬리에있는 ByteArrayOutputStream 바이트 시작한 후 파일 바이트를 판독한다.
두 가지 개선 할 필요가 : 1) 버퍼링 2) EOL 인식
전체 파일을 읽지 않고 BufferedReader를 사용하는 방법을 포함 할 수 있습니까? –
한 줄씩 읽으므로 전체 파일을 메모리로 읽지 않습니다. –
처음부터 줄 단위로 읽는 것이므로 전체 파일을 메모리로 읽어 들이고 있습니다. 전체 파일을로드하지 않더라도 한 번에 파일. –
당신이 랜덤 액세스를해야하는 경우 RandomAccessFile에 필요합니다. 자신이하는 일을 알고 있다면 바이트를 UTF-8로 변환 할 수 있습니다.
BuffredReader를 사용하는 경우 skip (n)을 문자 수만큼 사용할 수 있습니다. 즉, 전체 파일을 읽어야합니다.
이렇게 조합하는 방법; FileInputStream을 skip()과 함께 사용하고 N 개 줄 바꾸기를 읽고 BufferedReader에서 스트림을 래핑하여 UTF-8 인코딩으로 줄을 읽으려는 곳을 찾으십시오.
결국, 하루가 끝나면 전체 파일을 읽는 것입니다. 기억에? –
내가 제안한대로하지 않는다. BufferedReader를 단독으로 사용하면 전체 파일을 읽을 수 있습니다. 그렇게하는 것이 좋습니다. –
이 초보자를위한 코드 스 니펫을 공유 할 수 있습니까? (. 파일 끝까지 도달하고, n 줄까지 추적 한 다음, n 줄을 내 메모리에서 읽으려고합니다. –
아니요. 'seek()'은 전체 파일을 제외하고 메모리에 * anything *을 읽지 않습니다. 너는 모든 권한을 가지고있다. – NPE
그 질문을 통해 읽었지만 UTF-8로 인코딩 된 파일의 경우 RandomAccessFile을 사용하면 낙담한지 이해하고 싶습니다. –
복제본에 동의하지 않습니다. 이것은 RandomAccessFile에 더 초점을 맞추고, 다른 하나는 응용 프로그램에 대한 것이고 RAF는 언급하지 않습니다. –