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?

[2245 byte] By [@GeneAnthonya] at [2007-11-27 1:29:37]
# 1

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).

KathyMcDonnella at 2007-7-12 0:29:28 > top of Java-index,Java Essentials,Java Programming...
# 2

@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

kajbja at 2007-7-12 0:29:28 > top of Java-index,Java Essentials,Java Programming...
# 3
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?
@GeneAnthonya at 2007-7-12 0:29:28 > top of Java-index,Java Essentials,Java Programming...
# 4

> 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)

KathyMcDonnella at 2007-7-12 0:29:28 > top of Java-index,Java Essentials,Java Programming...