I have an EJB client that needs to retrieve a large file from an EJB server (JBoss).
The evident way to implement this is the server to offer a EJB facade with a method like this one:
public byte[] getFile(String fileName);
That means, loading the whole file in memory, in a byte array, and then sending this byte array on the wire.
The problem is that this approach loads the whole file in memory, and since the file is huge, it would overflow it.
Is there any option to overcome this problem?
HTTP would be a better choice, but that said, try this serialization trick:
import java.io.*;
public class FileContent implements Serializable {
private transient File file;
public FileContent() {
}
public FileContent(File file) {
this.file = file;
}
private void writeObject(ObjectOutputStream out) throws IOException {
// 1. write the file name
out.writeUTF(file.getAbsolutePath());
// 2. write the length
out.writeLong(file.length());
// 3. write the content
final InputStream in = new BufferedInputStream(new FileInputStream(file));
final byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
out.flush();
in.close();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// 1. read the file name
final String path = in.readUTF();
// 2. read the length
long remaining = in.readLong();
// 3. read the content
file = new File(path);
final OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
final byte[] buffer = new byte[1024];
while (true) {
int length = in.read(buffer, 0, (int) Math.min(remaining, buffer.length));
if (length == -1) break;
out.write(buffer, 0, length);
remaining -= length;
if (remaining <= 0) break;
}
out.flush();
out.close();
}
}
The RMIIO library was built for exactly this situation. It even includes an implementation of @DavidBlevins solution, the DirectRemoteInputStream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With