나이 검색되었습니다 많은 가장 빠른 방법을 읽고 쓰는 다시 큰 파일(0.5-1 기가바이트)에서 자바 메모리가 제한된(에 대해 64MB). 각 라인에서 파일을 나타내 기록,그래서 나는 데 필요한 라인에 의해 라인입니다. 이 파일은 일반 텍스트 파일입니다.
나 BufferedReader 및 BufferedWriter 지't 것 같 최선의 선택입니다. 약 35 초을 읽고 쓰는 파일의 크기가 0.5 기가바이트,읽기 쓰기만 없이 처리합니다. 나는 생각한 병목 현상이 여기는 서면으로 읽는 혼자가 약 10 초입니다.
을 읽으려고 시도했 바이트 배열을,그러나 찾기 위해 라인에서 각각하는 배열을 읽은 시간이 더 오래 걸립니다.
어떤 제안을까요? 감사
심의 진짜 문제는 당신이 제한 하드웨어 그리고 당신은 무엇이 소't 들에게 많은 차이입니다. 는 경우에 당신은 많은 메모리 및 CPU,고급 트릭 도울 수 있지만,당신은 그냥 기다리고 하드 드라이브에 있는 파일 캐시되지 않은,그't 들에게 많은 차이입니다.
BTW:500 메가바이트에 10 초 50MB/sec 은 일반적인 읽기 속도를 위해 하드 디스크 드라이브.
을 실행하려면 다음을 참조하 어떤 지점에서 시스템을 수 없을 캐쉬 파일을 효율적으로 합니다.
public static void main(String... args) throws IOException {
for (int mb : new int[]{50, 100, 250, 500, 1000, 2000})
testFileSize(mb);
}
private static void testFileSize(int mb) throws IOException {
File file = File.createTempFile("test", ".txt");
file.deleteOnExit();
char[] chars = new char[1024];
Arrays.fill(chars, 'A');
String longLine = new String(chars);
long start1 = System.nanoTime();
PrintWriter pw = new PrintWriter(new FileWriter(file));
for (int i = 0; i < mb * 1024; i++)
pw.println(longLine);
pw.close();
long time1 = System.nanoTime() - start1;
System.out.printf("Took %.3f seconds to write to a %d MB, file rate: %.1f MB/s%n",
time1 / 1e9, file.length() >> 20, file.length() * 1000.0 / time1);
long start2 = System.nanoTime();
BufferedReader br = new BufferedReader(new FileReader(file));
for (String line; (line = br.readLine()) != null; ) {
}
br.close();
long time2 = System.nanoTime() - start2;
System.out.printf("Took %.3f seconds to read to a %d MB file, rate: %.1f MB/s%n",
time2 / 1e9, file.length() >> 20, file.length() * 1000.0 / time2);
file.delete();
}
Linux 시스템에서의 많은 메모리입니다.
Took 0.395 seconds to write to a 50 MB, file rate: 133.0 MB/s
Took 0.375 seconds to read to a 50 MB file, rate: 140.0 MB/s
Took 0.669 seconds to write to a 100 MB, file rate: 156.9 MB/s
Took 0.569 seconds to read to a 100 MB file, rate: 184.6 MB/s
Took 1.585 seconds to write to a 250 MB, file rate: 165.5 MB/s
Took 1.274 seconds to read to a 250 MB file, rate: 206.0 MB/s
Took 2.513 seconds to write to a 500 MB, file rate: 208.8 MB/s
Took 2.332 seconds to read to a 500 MB file, rate: 225.1 MB/s
Took 5.094 seconds to write to a 1000 MB, file rate: 206.0 MB/s
Took 5.041 seconds to read to a 1000 MB file, rate: 208.2 MB/s
Took 11.509 seconds to write to a 2001 MB, file rate: 182.4 MB/s
Took 9.681 seconds to read to a 2001 MB file, rate: 216.8 MB/s
Windows 시스템에서의 많은 메모리입니다.
Took 0.376 seconds to write to a 50 MB, file rate: 139.7 MB/s
Took 0.401 seconds to read to a 50 MB file, rate: 131.1 MB/s
Took 0.517 seconds to write to a 100 MB, file rate: 203.1 MB/s
Took 0.520 seconds to read to a 100 MB file, rate: 201.9 MB/s
Took 1.344 seconds to write to a 250 MB, file rate: 195.4 MB/s
Took 1.387 seconds to read to a 250 MB file, rate: 189.4 MB/s
Took 2.368 seconds to write to a 500 MB, file rate: 221.8 MB/s
Took 2.454 seconds to read to a 500 MB file, rate: 214.1 MB/s
Took 4.985 seconds to write to a 1001 MB, file rate: 210.7 MB/s
Took 5.132 seconds to read to a 1001 MB file, rate: 204.7 MB/s
Took 10.276 seconds to write to a 2003 MB, file rate: 204.5 MB/s
Took 9.964 seconds to read to a 2003 MB file, rate: 210.9 MB/s
첫 번째 일을 하는 것은 증가하는 버퍼 크기의 BufferedReader 및 BufferedWriter. 기본 버퍼 크기를 설명하지 않지만,최소한 Oracle VM 그들은 8192,문자는't 고 성능 이점이다.
만 필요한 경우 복사본을 만들기 위해 파일의(그리고 don't 필요한 실제 데이터 액세스),나는 것 중 하나 삭제 리더/라이터의 접근과 작품으로 직접 InputStream 과 OutputStream 를 사용하여 바이트 배열로 완충기:
FileInputStream fis = new FileInputStream("d:/test.txt");
FileOutputStream fos = new FileOutputStream("d:/test2.txt");
byte[] b = new byte[bufferSize];
int r;
while ((r=fis.read(b))>=0) {
fos.write(b, 0, r);
}
fis.close();
fos.close();
또는 실제로 사용하 NIO:
FileChannel in = new RandomAccessFile("d:/test.txt", "r").getChannel();
FileChannel out = new RandomAccessFile("d:/test2.txt", "rw").getChannel();
out.transferFrom(in, 0, Long.MAX_VALUE);
in.close();
out.close();
할 때 벤치마킹하는 다양한 복사 방법,그러나 나는 훨씬 더 큰 차이(시간)사이의 각 실행하는 벤치마크보다 사이의 다른 구현입니다. I/O 캐싱(에 모두 OS 레벨 및 하드 디스크 캐시)여기에 큰 역할을 한 그리고 그것은 매우 어려운 말은 빠릅니다. 에 내 하드웨어를 복사,1GB 텍스트 파일로 라인으로 라인을 사용하여 BufferedReader 및 BufferedWriter 보 5s 에서 실행하고 30 대이상 다른.
Java7 사용할 수 있는 파일입니다.readAllLines()및 파일이 있습니다.write()방법이 있습니다. 여기를 들어:
List<String> readTextFile(String fileName) throws IOException {
Path path = Paths.get(fileName);
return Files.readAllLines(path, StandardCharsets.UTF_8);
}
void writeTextFile(List<String> strLines, String fileName) throws IOException {
Path path = Paths.get(fileName);
Files.write(path, strLines, StandardCharsets.UTF_8);
}
내가 권하고 클래스 java.nio`패키지입니다. Non-blocking IO 빠를 수도 있습에 대한 sockets:
http://docs.oracle.com/javase/6/docs/api/java/nio/package-summary.html
이 문서는 벤치마크는's true:
http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html
가 작성된 광범위한 기사에 대한 많은 방법의파일을 읽는 자바및 그들을 테스트 서로에 대하여 샘플 파일에서 1 킬로바이트 1GB 과 내가 찾은 다음 3 가지 방법을 했다 가장 빠르게 읽기 위해 1 기가바이트 파일:
1)java.nio.파일입니다.파일이 있습니다.readAllBytes()-took just under1 초를 읽 1GB 테스트 파일입니다.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class ReadFile_Files_ReadAllBytes {
public static void main(String [] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
byte [] fileBytes = Files.readAllBytes(file.toPath());
char singleChar;
for(byte b : fileBytes) {
singleChar = (char) b;
System.out.print(singleChar);
}
}
}
2)java.nio.파일입니다.파일이 있습니다.선()-에 걸렸다가 3.5 초에는 1GB 테스트 파일입니다.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
3)java.io.BufferedReader-했에 대한 4.5 초을 읽는 1GB 테스트 파일입니다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
}
It's 에 대한 모든OutOfMemoryException
할 수 있는 효율적으로 처리를 통해 스캐너 클래스의 반복기입니다. 그것을 읽어 파일이 라인에 의해 선하지 않습니다.
아래 코드를 문제를 해결합:
도(수 fileinputstream 에 inputStream=new 수 fileinputstream 에("D:\\File\\test.txt"); 스캐너 sc=새로운 스캐너(inputStream,"UTF-8")){ 동(sc.hasNextLine()){ 문자열에 줄=sc.nextLine(); 시스템입니다.니다.system.out.println(선); } }catch(IOException e){ e.printStackTrace(); }