views:

464

answers:

3

I am looking for an efficient way to create a file whose size is unknown but can range from mb's to gb's and fill its content randomly. I may write first 200 bytes than jump to the end and write last 200 bytes and move to the middle and write there. Is RandomAccessFile efficient for doing this or are there any alternatives better suited for this kind of job?

+10  A: 

Yes, use RandomAccessFile - that's what it's there for. You could potentially use a FileChannel, but I'd go for RandomAccessFile first - it's likely to be simpler.

Note that you won't be able to "insert in the middle" of the file after writing the end part: I don't know any file system which supports that. You'll need to know the complete size before you write the final section, basically. An alternative would be to write sequentially, remembering the final bit until the end.

If you can give us more information about what you need to do (and when you have information about the size) we may be able to help you more.

EDIT: To create the file with a specific size,you can seek() past the end and then write data:

import java.io.*;

public class Test
{
    // Just for the sake of a simple test program!
    public static void main(String[] args) throws Exception
    {
        RandomAccessFile file = new RandomAccessFile("file.dat", "rw");

        file.seek(100);
        file.write(0);
        file.close();
    }
}

After this has exited, file.dat will be 101 bytes long. (Note that normally you'd use try/finally etc.)

EDIT: As coobird mentioned in the comments, setLength() will also extend the file - but it will also truncate the file if you give a length less than the current size. Given your comment about basically writing torrent data, I suspect that seeking and then writing is exactly the behaviour you want. When you receive a chunk, just seek to the right spot, write it out, and the file will extend itself when it needs to.

Jon Skeet
Is there a way to create file with a prefixed size other than iterating and writing all zero's or one's to fill it?
Hamza Yerlikaya
Editing to reflect this.
Jon Skeet
Thanks, the reason i have to write random parts in the file, is i am implementing a torrent client and pieces will arrive for random locations in the file, but i know before hand what the size of the whole file will be.
Hamza Yerlikaya
@Jon Skeet: How about the RandomAccessFile.setLength method? It says that it will extend the file if the newly specified size is larger than the current size (however, the data used to fill the extended portion is undefined). Could that work in this case?
coobird
Yes - I hadn't spotted that. Doh! Will edit.
Jon Skeet
Most modern OS-es don't allocate sectors on disk until you actually write some data into a position within a file. Therefore, torrent clients offer the option to pre-allocate the file to avoid disk-trashing later on when the random chunks arrive.
kd304
+1  A: 

I guess RandomAccessFile is fine for this problem

joe
+2  A: 

RandomAccessFile should do it