Hi I have created two approaches to create big files, run program on windows 7, 64-bit, 8 GB RAM machine, JDK 8 and below are results.
In both the cases, file of 180 MB created that contains number in each line from 1 to 20 million (2 crore in Indian system).
Java program memory grows gradually till 600 MB
First output
Approach = approach-1 (Using FileWriter) Completed file writing in milli seconds = 4521 milli seconds.
Second output
Approach = approach-2 (Using FileChannel and ByteBuffer) Completed file writing in milli seconds = 3590 milli seconds.
One observation - I am calculating position (pos variable) in approach#2, if I comment it out then only last string will be visible due to overwritten at position, but time reduced to nearly 2000 milli seconds.
Attaching code.
import java.io.FileWriter; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.TimeUnit; public class TestLargeFile { public static void main(String[] args) { writeBigFile(); } private static void writeBigFile() { System.out.println("--------writeBigFile-----------"); long nanoTime = System.nanoTime(); String fn = "big-file.txt"; boolean approach1 = false; System.out.println("Approach = " + (approach1 ? "approach-1" : "approach-2")); int numLines = 20_000_000; try { if (approach1) { //Approach 1 -- for 2 crore lines takes 4.5 seconds with 180 mb file size approach1(fn, numLines); } else { //Approach 2 -- for 2 crore lines takes nearly 2 to 2.5 seconds with 180 mb file size approach2(fn, numLines); } } catch (IOException e) { e.printStackTrace(); } System.out.println("Completed file writing in milli seconds = " + TimeUnit.MILLISECONDS.convert((System.nanoTime() - nanoTime), TimeUnit.NANOSECONDS)); } private static void approach2(String fn, int numLines) throws IOException { StringBuilder sb = new StringBuilder(); FileChannel rwChannel = new RandomAccessFile(fn, "rw").getChannel(); ByteBuffer wrBuf; int pos = 0; for (int i = 1; i <= numLines; i++) { sb.append(i).append(System.lineSeparator()); if (i % 100000 == 0) { wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, pos, sb.length()); pos += sb.length(); wrBuf.put(sb.toString().getBytes()); sb = new StringBuilder(); } } if (sb.length() > 0) { wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, pos, sb.length()); wrBuf.put(sb.toString().getBytes()); } rwChannel.close(); } private static void approach1(String fn, int numLines) throws IOException { StringBuilder sb = new StringBuilder(); for (int i = 1; i <= numLines; i++) { sb.append(i).append(System.lineSeparator()); } FileWriter fileWriter = new FileWriter(fn); fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); } }
textToSavestring might dominate the time.