Question about file copy operations
I'm new to Java file copies and one thing I always notice is that when people set the bytes to copy it always seems to be 4096. I was wondering why this is? For example here is a simple copy method:
publicstaticvoid copy(String fromFileName, String toFileName)throws IOException{
File fromFile =new File(fromFileName);
File toFile =new File(toFileName);
FileInputStream from =null;
FileOutputStream to =null;
try{
from =new FileInputStream(fromFile);
to =new FileOutputStream(toFile);
byte[] buffer =newbyte[4096];
int bytesRead;
while ((bytesRead = from.read(buffer)) != -1)
to.write(buffer, 0, bytesRead);// write
}finally{
if (from !=null)
try{
from.close();
}catch (IOException e){
;
}
if (to !=null)
try{
to.close();
}catch (IOException e){;}
}
}
When they set the buffer it's set as a byte array of 4096 characters. How come?
4096 is exactly 1 "virtual memory page" on a x86 microprocessor.
On many operating systems and runtime environment implementations on x86,
when you allocate a memory block that is around 4096 bytes in size,
then the OS will "round it up" to 4096. So you might as well get the full size.
Edit: Of course, JVM actually adds overhead.
So you might get less memory fragmentation if you deliberately
use a size that is "a few bytes" smaller than 4096 (eg. 4060 or something).
@Op. This doesn't answer your question, but this is how I would copy a file:
import java.nio.*;
import java.nio.channels.*;
import java.io.*;
public class ChannelDemo4 {
public static void main(String args[])
throws IOException {
// check command-line arguments
if (args.length != 2) {
System.err.println("missing filenames");
System.exit(1);
}
// get channels
FileInputStream fis =
new FileInputStream(args[0]);
FileOutputStream fos =
new FileOutputStream(args[1]);
FileChannel fcin = fis.getChannel();
FileChannel fcout = fos.getChannel();
// do the file copy
fcin.transferTo(0, fcin.size(), fcout);
// finish up
fcin.close();
fcout.close();
fis.close();
fos.close();
}
}
Directly taken from:
http://java.sun.com/developer/JDCTechTips/2002/tt0507.html
Kaj
> Thank you for the replies. Read up a little on
> virtual memory pages. I was wondering how come you
> have to specify this? This seems to be standard and
> I was wondering why do they even ask you what you'd
> like to use. Is there a reason you wouldn't set it
> at say 4060?
The real answer is the one kajbj gave: just use the existing facility
to copy the file. The JVM will probably automatically optimize it.
But, if the programmer insists on doing his/her own buffer management,
then you have to set the buffer size yourself. If you set it too small, you end up
calling the OS over-and-over again. If you set it too large, you waste runtime memory
and also you break cache locality. So... best not to worry too much.
(The 4096-rule is just something that C/C++ old-timers automatically do)