Как передать InputStream через RMI - PullRequest
2 голосов
/ 17 августа 2011

Рассмотрим эти две функции:

Function A принимает inputStream в качестве параметра.

public void processStream(InputStream stream)
{
  //Do process routine
}

Function B загружает содержимое файла, чтобы передать его Function A как InputStream.

pulic void loadFile()
{
 File file =new File("c:\\file.txt");
 //Pass file as InputStream
}

Как передать файл из Function B в Function A как InputStream, не читая его из первых рук?

Я сделал что-то вроде этого:

File file = new File("c:\\file.txt");
DataInputStream stream= new DataInputStream(new FileInputStream(file));

Это сгенерировало исключение ниже:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.io.DataInputStream

РЕДАКТИРОВАТЬ:

loadFile() передает InputStream как ответ RMI.

Ответы [ 3 ]

3 голосов
/ 17 августа 2011

Следующее должно работать нормально

processStream(new FileInputStream(file));

Вы должны только не пытаться сериализовать InputStream экземпляр ObjectOutputStream, например

objectOutputStream.writeObject(inputStream);

что вы, очевидно, делаете в processStream() методе.Это именно то, что пытается сказать вам исключение.Как ее решить правильно, зависит от единственного функционального требования, которое вы пропустили в вопросе.


Обновление согласно комментарию

Я передаю InputStream как ответ RMI.

Проблема есть.Вы не можете передавать несериализуемые объекты как ответ RMI, не говоря уже о непрочитанных потоках.Вам нужно прочитать InputStream в ByteArrayOutputStream обычным способом ввода-вывода, а затем использовать его toByteArray(), чтобы получить byte[] и передать его вместо этого.Что-то вроде:

InputStream input = new FileInputStream(file); 
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];

for (int length = 0; (length = input.read(buffer)) > 0;) {
    output.write(buffer, 0, length);
}

byte[] bytes = output.toByteArray(); // Pass that instead to RMI response.

Будьте осторожны с большими файлами.Каждый байт byte[] съедает один байт памяти JVM.

0 голосов
/ 17 августа 2011

Это исключение указывает на то, что вы вызываете метод processStream для удаленного объекта, используя что-то вроде RMI?если это так, вам нужно будет повторно посетить то, что вы делаете.отправка потоков данных через RMI - нелегкая задача.если вы гарантированно используете небольшие файлы, вы можете скопировать данные файла в byte[] и передать их удаленному вызову метода.однако если вам нужно обрабатывать большие файлы, это, скорее всего, вызовет проблемы с памятью на клиенте и / или сервере.в этом случае вы должны использовать что-то вроде rmiio , которое предоставляет утилиты для потоковой передачи данных через RMI.

0 голосов
/ 17 августа 2011

Вы могли бы просто передать FileInputStream?

processStream(new FileInputStream(yourFile));

Причина, по которой вы получаете исключение, заключается в том, что DataInputStream предназначен для чтения примитивных типов Java

...