pdf Datei mit rmi übertragen

schuetzejanett

Erfahrenes Mitglied
Hallo,

ich schreibe eine client-server Applikation über rmi.
Auf dem server befindet sich eine pdf Datei, wie bekomme ich diese zum Client. Möchte sia auf dem client eigentlich nur anschauen und drucken.

Hab aber keine so rechte idee, wie ich das anstelle, also wie sieht meine interface methode, die methode des servers und die des clients zum aufruf aus.
Und muss ich beim aufruf angeben wo ich die daei speichern will, oder mache ich das dann wen ich sie habe?. Und welchen rückgabetyp hat die methode um die pdf datei zu speichern?

Freue mich über anregungen und codebsp, weil ich irgendwie total auf dem schlauch stehe.
 
Also am einfachsten

1. Du legst dir einen eigenen Typen an der Serializable ist und der den Bytestrom der PDF Datei aufnehmen kann.
2. Die Remote Methode des Servers hat als Rückgabe diesen Typen
3. Beim Aufruf der Remote Methode übergibst du den Dateinamen des PDF's, der Server sucht die Datei schreibt sie in dein Objekt (von deinem Typen) und übergibt sie der Rückgabe (return der Methode)
4. der Client empf. das Objekt (und dann kannst du die Datei wieder anlegen oder gleich verarbeiten)

(P.S. der Typ muss dem Client bekannt)
 
hallo,

ok ich lege mir also eine klasse pdfFile an, welche ich dann übergebe, alles klar, aber wenns auch ne blöde frage ist, die klasse enthält ein attribut stream vom typ Filestream ? oder ist der variablentyp ein anderer welche bytestromklassen gibts denn da?
 
Sitze jetzt leider nicht vorm richtigen Rechner um es zu testen.
Auf jeden Fall darf es kein Stream sein da dies ja nur eine Referenz auf eine Quelle ist.(und diese sind nicht serialisierbar)
Vielleicht einen
java.util.Vector<byte> buffer=new java.util.Vector<byte>();
(oder ähnliche Containerklasse) denke mal Vector ist nicht so gut aber geht auf jeden Fall.
Und dann liest du das File byte für byte in diesen Vector und überträgst das Obj. welches den Vector enthält zum Client.
Wenn der Client fertig ist musst du halt das Objekt wieder zerstören damit du den Speicher wieder frei gibst.

Also du musst das File auf jeden Fall komplett zum Client übertragen da du eine Referenz auf ein File(Stream) da nicht serial. auch nicht über RMI übertragen kannst.
 
SERVER


Datenhaltung
------------

public class pdfcase implements java.io.Serializable{

public java.util.Vector buffer;
public int offset=-1;

public pdfcase (java.util.Vector buf,int off){
buffer = buf;
offset = off;
}
}


Funktionalität
--------------

public class facility {

private java.util.Vector buffer;
private java.io.FileInputStream in;
private String dateiname;
private int lastlength;

public facility(String datei) {
try{
dateiname= datei;
in = new java.io.FileInputStream(datei);
buffer = new java.util.Vector();
byte[] b = new byte[4096];
int nbyte= -1;

while(-1!=(nbyte=(in.read(b)))){
lastlength=nbyte;
buffer.addElement(b.clone()); //tiefe kopie
}

in.close();
}catch(Throwable e){e.printStackTrace();}
}

public pdfcase getCase(){
return new pdfcase(buffer,lastlength);
}
}


Interface (Service)
-------------------

interface pdfservice extends java.rmi.Remote{
public pdfcase getPDF(String dateiname)throws java.rmi.RemoteException;
}

Service-Implementierung
-----------------------

public class serviceImple extends java.rmi.server.UnicastRemoteObject implements pdfservice{

public serviceImple ()throws java.rmi.RemoteException{}

public pdfcase getPDF(String dateiname)throws java.rmi.RemoteException{
return new facility(dateiname).getCase();
}

}


Main
----


public class Main {

public Main() {
try{
java.rmi.registry.Registry reg=
java.rmi.registry.LocateRegistry.createRegistry(6000);
System.out.println ("Registry gestartet");
reg.rebind ("pdfservice", new serviceImple());
System.out.println ("Service eingebunden");


}catch(Exception e){
e.printStackTrace();
}

}

public static void main(String[] args) {
new Main();
}

}


//dann naturlich mit <rmic serviceImple> den Stub erstellen
//Client benötigt serviceImple_Stub.class,pdfcase.class,pdfservice.class

CLIENT
------


public class Main {

public Main() {
try{
pdfservice service =(pdfservice)java.rmi.Naming.lookup("rmi://192.168.1.253:6000/pdfservice");
pdfcase c =(pdfcase)service.getPDF("E:\\test.pdf");
java.io.File file = new java.io.File("out.pdf");
file .createNewFile();
java.io.FileOutputStream out = new java.io.FileOutputStream(file);

for(int i=0;i<c.buffer.size();i++){
if(i==(c.buffer.size()-1))out.write((byte[])c.buffer.get(i),0,c.offset);
else out.write((byte[])c.buffer.get(i));
}

}catch(Exception e){
e.printStackTrace();
}
}

public static void main(String[] args) {
new Main();
}

}


//IP anpassen
//Dateipfad muss auf dem Server vorhanden sein
//die Datei wird bei mir nur kopiert
//in deinem Falle tempfile und über System.exec das PDF-File aufrufen (am besten im Browser)

ALSO ICH HOFFE DAS REICHT DIR VIEL SPAß
 
Hallo es fun ktioniert ,

Hätte aber mal noch ein paar kleinere Fragen.

1. warum kann ich nicht einfach nur ein byte[] übertragen , also ohne die länge und vektor
(byte array hat nur länge von datei und nicht standart, dann b räuchte ich je dieses lastlengh nicht )
2. kannst du mir mal deine einlese bzw schreibe mehoden erklären. mir ist das irgendwie zu viel code auf 4 zeilen, weiß zwar grob das du einmal solange noch zeichen da sind einliest und dan wieder schreibst, aber so richtig eben nicht.

hier sind die zeilen die ich meine.

Java:
//im Server
while(-1!=(nbyte=(in.read(b)))){ 
lastlength=nbyte; 
buffer.addElement(b.clone()); //tiefe kopie
}

und im Client//
for(int i=0;i<c.buffer.size();i++){
if(i==(c.buffer.size()-1))out.write((byte[])c.buffer.get(i),0,c.offset);
else out.write((byte[])c.buffer.get(i)); 
}

Kannst du mir diese 2 fragen bitte noch beantworten?
 
Frage 1: es ist natürlich richtig du könntest auch die Dateilänge abfragen und ein Bytefeld mit dieser Länge anlegen dann brauchst du diesen Wert nicht. Also auf performance hab ich nicht geachtet wollte dir nur eine Möglichkeit aufzeigen.

Frage 2:

for(int i=0;i<c.buffer.size();i++) //ist klar c ist das Object buffer der Vector also iter. über die Länge des Vektors

if(i==(c.buffer.size()-1))out.write((byte[])c.buffer.get(i),0,c.offset); //das brauchst du natürlich nicht mehr wenn du deinen Gedanken verfolgst hier frage ich einfach nur ob ich das letzte Element im Vector erreicht habe wenn ja hole ich mir das byte feld und schreibe es nur von 0 bis eigentliche Länge da es ja wahrscheinlich nicht 4096 byte gefüllt wurde. Und musste natürlich auf byte[] casten da der Vector typlos war

else out.write((byte[])c.buffer.get(i)); //wenn nicht schreibe ich die 4096 bytes

//wie gesagt das brauchst du nicht wenn du die Datei in ein byte[] schreibst
//du musst nur immer auf die tiefe Kopie achten

Hoffe alle deine Fragen sind beantwortet, wenn nicht nur zu.
Würde mich über ein Renommee freuen.
 
Hallo,

bin ja auch froh das du mir so gut geholfen hast, sollte auch keine kritik sein, habe eben bloß überlegt ob das auch so geht also nur mit byte array, das möchte ich jetzt gerne mal probieren, allerdings habe ich da schon das nächste problem, wie komm ich zur dateigröße , habe schon versucht die datei als file zu deklariern und dort length() ausgelesen ist aber wesentlich höher, als bei deiner variante lastlength. Oder muss ich das noch irgendwie umrechnen?
 
Das ist schon der richtige Weg als File und dann die length bei mir die lastlength kann ja nur eine Zahl zwischen 0 und 4096 sein da sie mir nur aussagen soll wie weit der letzte puffer gefüllt ist. Also ich lese immer 4096 byte der Datei ein n mal ein und wenn ich am Ende angekommen bin wird der letzte puffer mit hoher Wahrscheinlichkeit nich mehr voll und darum die lastlength.

P.S. hab es auch nicht als Kritik aufgefasst:)
 
Achso , ja aber dann werde ich doch auf deine variante umsteigen müssen weil ich für meine dateigröße so um die 200 kB ist und ich ja aber nur arrays mit einer int Länge anlegen kann. Oder?
 

Neue Beiträge

Zurück