Using a Buffer

Dear all ,

I need to transfer files of unknown maximum size into an array of bytes

i',m using this code :

FileInputStream fis =new FileInputStream(oldPath);

byte[] bytes =newbyte[fis.available()];

fis.read(bytes, 0, fis.available());

fis.close();

but on transferring an exe of size 154 MG , i got heap out of memory exception , so how can i improve my code to make use of buffers?

i have no idea how can i do so ?

can anybody help me ?

wishing to find any reply

thanks in advance.

Regards,

D.Roth

[721 byte] By [d_rotha] at [2007-11-27 2:31:40]
# 1
Remind us why you need to hold the entire file in memory.
DrLaszloJamfa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 2
actually i'm implementing huffman algorithm , that's why i need to save the entire file in memory
d_rotha at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 3
I'm rusty on that algorithm, but I thought it made passes though the data. Is there really a need to hold it all in memory at the same time?
DrLaszloJamfa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 4

> Dear all ,

> I need to transfer files of unknown maximum size

> into an array of bytes

> ',m using this code :

>

> > FileInputStream fis = new FileInputStream(oldPath);

> byte[] bytes = new byte[fis.available()];

> fis.read(bytes, 0, fis.available());

> fis.close();

>

> but on transferring an exe of size 154 MG , i got

> heap out of memory exception , so how can i improve

> my code to make use of buffers?

> i have no idea how can i do so ?

> can anybody help me ?

> wishing to find any reply

> thanks in advance.

> Regards,

> D.Roth

You try:

File file = new File(oldPath); // figuring oldPath is the file name

byte[] bytes = file.length();

FileInputStream fis = new FileInputStream(file);

int done = fis.read(bytes);

fis.close();

-and-

cmd /c start /min java -Xms128m -Xmx1024m YouClassFileNameHere

... Substituting the numbers you want for Xms and Xmx ?

abillconsla at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 5
i tried your code , thank u very much , but i have the same problem , it is big ( heap ou of memory ) , i need to divide the file using the buffer.so any ideas?
d_rotha at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 6

well if that is the case why don;t you go about employee classical paging methodology for your data in this case...

where you would divide the filedatabuffer into 'N' equal parts get and the data into the byte array of length equal to filedatabuffer / N which is manageable apply huffaman algorithm pass it to OutputStream & then read next part apply & so on....

In general pagination could be one of the best solutions for these sort of issues else where U wud keep getting Bonkered Memory Exceptions.

NOTE: Streaming of video is done in a similar way.

& It would be gr8 if you can devise a way by which you generate the page size dynamically i'm sure a simple google serch would help U on that..

Hope that might help :)

REGARDS,

RaHuL

RahulSharnaa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 7
Plan B - as mentioned by others ... tell us (we who don't know the Math thingy, that is) why you need all the file in mem?
abillconsla at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 8

import java.io.*;

import java.util.*;

/**

* BigFileReader contains two methods to read a file from a file system.

* Two methods are used to illustrate optimized reading abilities

*

* @version 1.0

*/

public class BigFileReader {

/**

* Default constuctor

*/

public BigFileReader(){ }

/**

* Reads a file storing intermediate data into a list. Fast method.

* @param file the file to be read

* @return a file data

*/

public byte[] read2list(String file) throws Exception {

InputStream in = null;

byte[] buf = null; // output buffer

intbufLen = 20000*1024;

try{

in = new BufferedInputStream(new FileInputStream(file));

buf = new byte[bufLen];

byte[] tmp = null;

int len= 0;

List data = new ArrayList(24); // keeps peaces of data

while((len = in.read(buf,0,bufLen)) != -1){

tmp = new byte[len];

System.arraycopy(buf,0,tmp,0,len); // still need to do copy

data.add(tmp);

}

/*

This part os optional. This method could return a List data

for further processing, etc.

*/

len = 0;

if (data.size() == 1) return (byte[]) data.get(0);

for (int i=0;i<data.size();i++) len += ((byte[]) data.get(i)).length;

buf = new byte[len]; // final output buffer

len = 0;

for (int i=0;i<data.size();i++){ // fill with data

tmp = (byte[]) data.get(i);

System.arraycopy(tmp,0,buf,len,tmp.length);

len += tmp.length;

}

}finally{

if (in != null) try{ in.close();}catch (Exception e){}

}

return buf;

}

/**

* Reads a file storing intermediate data into an array.

* @param file the file to be read

* @return a file data

*/

public byte[] read2array(String file) throws Exception {

InputStream in = null;

byte[] out = new byte[0];

try{

in = new BufferedInputStream(new FileInputStream(file));

// the length of a buffer can vary

int bufLen = 20000*1024;

byte[] buf = new byte[bufLen];

byte[] tmp = null;

int len= 0;

while((len = in.read(buf,0,bufLen)) != -1){

// extend array

tmp = new byte[out.length + len];

// copy data

System.arraycopy(out,0,tmp,0,out.length);

System.arraycopy(buf,0,tmp,out.length,len);

out = tmp;

tmp = null;

}

}finally{

// always close the stream

if (in != null) try{ in.close();}catch (Exception e){}

}

return out;

}

/**

* Creates a big file with given name

* @param file the file name

*/

public void createData(String file) throws Exception {

BufferedOutputStream os = new BufferedOutputStream(

new FileOutputStream(file));

byte[] b = new byte[]{0xC,0xA,0xF,0xE,0xB,0xA,0xB,0xE};

intc = 1000000;

for (int i=0;i<c;i++){

os.write(b);

os.flush();

}

}

/**

* Test two different data reading algorithms:

* First, it creates a file, then it reads data using read2list method and,

* finally, it reads data with read2array method.

*/

public static void main(String[] v) throws Exception {

BigFileReader bfr = new BigFileReader();

System.out.println("creating a file...");

bfr.createData("data.dat");

System.out.println("file created");

long t = System.currentTimeMillis();

byte[] b = bfr.read2list("data.dat");

t = System.currentTimeMillis()-t;

System.out.println("read "+(b == null ? 0 : b.length)+

" byte(s) with read2list method in "+t+" ms");

t = System.currentTimeMillis();

b = bfr.read2array("data.dat");

t = System.currentTimeMillis()-t;

System.out.println("read "+(b == null ? 0 : b.length)+

" byte(s) with read2array method in "+t+" ms");

}

}

>

java_2006a at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 9
[
RahulSharnaa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 10
Thank u every body , the problem is solved up to 45 MG ,i would try to optimizie more than that at the end of my work . thanks for now.
d_rotha at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 11
Well I imagine I am not one that contributed much help, but you're welcome jsut the same, as I am a part of the set of everyone.
abillconsla at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 12
Just throwing out an idea: would using a java.io.MappedByteBuffer avoid allocating a byte[] for the file?
DrLaszloJamfa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 13

Just for the record there is nothing 'optimal' about the code in reply #8. The read2list() and read2Array() methods both copy the data not twice but three times. It is possible to do all this with just one copy step, by using ByteArrayOutputStream for example, or by just allocating a byte[] buffer the correct size at the start.

But the whole idea of reading entire files of unknown size into memory is inherently suspect.

ejpa at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...
# 14
Err, I seem to recall implementing Huffman algorithm for some school project and it didn't require to have the whole file in the memory.Well the static version did, but not the dynamic.
-Kayaman-a at 2007-7-12 2:46:42 > top of Java-index,Java Essentials,Java Programming...