FileChannels를 사용하여 Java에서 큰 파일을 연결하는 데 더 효율적인 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/6065556

문제

Java에서 내 텍스트 파일을 연결하기위한 방법을 찾아내는 방법을 찾고 싶습니다. 누군가에게 어떤 통찰력이있는 경우, 이들은 FileChannel에 글을 쓰는 방법의 차이를 설명하는 커널 수준에서 무엇이든지 공유 할 수 있습니다.

문서 및 기타 스택 오버플로 대화에서 알 수있는 것과서, Allocatedirect는 드라이브에 공간을 할당하고 대부분 RAM을 사용하는 것을 방지합니다. iLocatedirect로 생성 된 bytebuffer가 파일 유입이 큰 경우 오버플로 또는 할당 할 수있는 잠재력이있을 수 있습니다. 1GB를 말하십시오. 이 시점 에서이 시점에서 파일이 2GB 이상이 아닌 소프트웨어 개발에서 보장됩니다. 그러나 미래에는 10 ~ 20GB만큼 큰 일이있을 수 있습니다.

나는 전송 루프가 한 번 이상 루프를 통과하지 못한다는 것을 관찰했다 ... 그래서 그것은 한 번에 전체 유입을 쓰는 데 성공하는 것으로 보인다; 그러나 나는 60MB보다 큰 파일로 그것을 테스트하지 않았습니다. 문서가 한 번에 얼마나 작성 될지 보장이 없음을 지정하기 때문에 문서가 반복됩니다. 이송 부품만으로, 내 시스템에서 int32를 count 매개 변수로 수락 할 수 있습니다, 시간에 2GB 이상을 지정할 수 없을 것입니다 ... 다시 커널 전문 기술이 나를 이해하는 데 도움이됩니다.

당신의 도움을 위해 미리 감사드립니다 !!

bytebuffer 사용 :

boolean concatFiles(StringBuffer sb, File infile, File outfile) {

    FileChannel inChan = null, outChan = null;

    try {

        ByteBuffer buff = ByteBuffer.allocateDirect((int)(infile.length() + sb.length()));
        //write the stringBuffer so it goes in the output file first:
        buff.put(sb.toString().getBytes());

        //create the FileChannels:
        inChan  = new RandomAccessFile(infile,  "r" ).getChannel();
        outChan = new RandomAccessFile(outfile, "rw").getChannel();

        //read the infile in to the buffer:
        inChan.read(buff);

        // prep the buffer:
        buff.flip();

        // write the buffer out to the file via the FileChannel:
        outChan.write(buff);
        inChan.close();
        outChan.close();
     } catch...etc

}
.

Trasferto (또는 transferfrom)를 사용하여 :

boolean concatFiles(StringBuffer sb, File infile, File outfile) {

    FileChannel inChan = null, outChan = null;

    try {

        //write the stringBuffer so it goes in the output file first:    
        PrintWriter  fw = new PrintWriter(outfile);
        fw.write(sb.toString());
        fw.flush();
        fw.close();

        // create the channels appropriate for appending:
        outChan = new FileOutputStream(outfile, true).getChannel();
        inChan  = new RandomAccessFile(infile, "r").getChannel();

        long startSize = outfile.length();
        long inFileSize = infile.length();
        long bytesWritten = 0;

        //set the position where we should start appending the data:
        outChan.position(startSize);
        Byte startByte = outChan.position();

        while(bytesWritten < length){ 
            bytesWritten += outChan.transferFrom(inChan, startByte, (int) inFileSize);
            startByte = bytesWritten + 1;
        }

        inChan.close();
        outChan.close();
    } catch ... etc
.

도움이 되었습니까?

해결책

transferTo() can be far more efficient as there is less data copying, or none if it can all be done in the kernel. And if it isn't on your platform it will still use highly tuned code.

You do need the loop, one day it will iterate and your code will keep working.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top