Avatar billede repsak Nybegynder
25. februar 2003 - 11:28 Der er 20 kommentarer og
1 løsning

Sende et worddocument

Heysa,
Er der nogle der ved hvordan jeg sende en fil (fx. et worddoc) fra en javaserver til en javaklient? Jeg kan godt sende almindelig tekst som fx et .txt dokument men filer hvor der indgår 'computertegn' virker ikke efter overførslen...

Jeg prøver pt. med Reader/Writer's subklasser (16-bit):

BufferedReader fromFile = new BufferedReader((new FileReader(file)));
PrintWriter recipient = new PrintWriter(socket.getOutputStream(),true);

Jeg har også prøvet med InputStream's subklasser (8-bit) men det virker heller ikke.

Jeg ville være glad for at se en lille kodestump :)
Kasper
Avatar billede arne_v Ekspert
25. februar 2003 - 11:53 #1
Brug enten OutputStream/InputStream eller
BufferedOutputStream/BufferedInputStream og
write & read metoder.
Avatar billede arne_v Ekspert
25. februar 2003 - 11:59 #2
Følgende er skrevet direkte ind utestet.

Server:

InputStream instr = new FileInputStream(filename);
OutputStream outstr = socket.getOutputStream();
int n;
byte[] b = new byte[1000];
while((n = instr.read(b)) >= 0) {
  outstr.write(b, 0, n);
}

Client:

InputStream instr = socket.getInputStream();
OutputStream outstr = new FileOutputStream(filename);
int n;
byte[] b = new byte[1000];
while((n = instr.read(b)) >= 0) {
  outstr.write(b, 0, n);
}
Avatar billede repsak Nybegynder
25. februar 2003 - 12:07 #3
Takker - jeg smider det lige i testeren :-)
Avatar billede repsak Nybegynder
25. februar 2003 - 13:11 #4
Jeg sidder lidt fast... hvordan får jeg overført filens data til byte arrayet? Er det smart at fyre hele filen ned i et array hvis det er en stor fil?
Avatar billede arne_v Ekspert
25. februar 2003 - 13:40 #5
Den server kode jeg har skitseret ovenfor læser ikke hele
filen op i et array.

Den tager 1000 bytes af gangen.
Avatar billede arne_v Ekspert
25. februar 2003 - 13:42 #6
Og while instr.read løkken læser altså op fra fil til byte array.
Avatar billede repsak Nybegynder
26. februar 2003 - 15:38 #7
Efter lang tids test er jeg kommet frem til noget underligt:
Først ankommer filens sidste data og dernæst ankommer filens første data.
Klient:
void start(){
        while(true){
            try{               
                String in = reader.readLine();               
                if(in == null) continue;
               
                if(in.equals("filetransfer:")){
                    File f = new File("c:/" , in=reader.readLine());
                    ChatWindow.getSingleton().addText("Recieve " +in);
                    BufferedInputStream instr = new BufferedInputStream(socket.getInputStream());
                    BufferedOutputStream outstr = new BufferedOutputStream(new FileOutputStream(f));
                   
                    int n = 0;
                    byte[] b = new byte[1000];
                    System.out.println("HER n="+n);
                    while((n = instr.read(b)) >= 0){
                        System.out.println("In while n="+n);
                        outstr.write(b, 0, n); 
                          outstr.flush();
                          if(n != 1000) break;
                    }                   
                    System.out.println("After while n="+n);
                    //outstr.flush();               
                    outstr.close();
                    ChatWindow.getSingleton().addText(f.getName() + " recieved");
                }
                else ChatWindow.getSingleton().addText(in);
            }
            catch(IOException e){
                System.out.println("IO 211 " + e);
                e.printStackTrace();
                return;           
            }           
        }
    }

Server:
int sendFile(){
        int counter = dld.getCounter();
        try{
            fromFile = new BufferedInputStream(new FileInputStream(file));
            toSocket = new BufferedOutputStream(recipient.getOutputStream());
            recipient.writeln("filetransfer:");
            recipient.writeln(file.getName());
       
            //fromFile.skip(counter);
            int n;
            byte[] b = new byte[(int)file.length()];
           
            while((n = fromFile.read(b)) >= 0) {
                toSocket.write(b, 0, n);
            }
            return OK;
        }
        catch(FileNotFoundException e){
            return NO_FILE;
        }
        catch(IOException e){
            System.out.println(e);
            return IO_ERROR;
        }       
    }

What's wrong?
Kasper
Avatar billede arne_v Ekspert
26. februar 2003 - 15:50 #8
Jeg kan ikke lige forklare fænomenet, men et par kommentarer,
som måske kan hjælpe lidt.

Server ser meget fornuftig ud.

Du kan sagtens nøjes med at allokere et byte array af størrelse
1000 - ingen grund til at allokere filens størrelse.

Client kan jeg ike helt forstå !
Avatar billede arne_v Ekspert
26. februar 2003 - 15:54 #9
while((n = instr.read(b)) >= 0){
                        System.out.println("In while n="+n);
                        outstr.write(b, 0, n); 
                          outstr.flush();  // <----------
                          if(n != 1000) break;  // <----------

                    }                   

Den outstr.flush() må være helt unødvendig. Data bliver flushet,
når du closer filen. Og før kan du ike bruge den alligevel.

Men jeg forstår slet ikke den if break !  Den tror jeg kan lave
mange ulykker, fordi selvom du har fået mindre end 1000 bytes, så
kan der godt komme mere data (read returnerer -1 når der ikke er mere data
og det fanger while løkken). Og de data må gå tabt.
Avatar billede arne_v Ekspert
26. februar 2003 - 15:57 #10
Og så er der et potentielt problem i både server og client.

Der laves BufferedReader/PrintWriter og BufferedInputStream/BufferedOutputStream
til samme socket.

Det tror jeg kan gå meget galt.

Mit forslag er helt at droppe BufferedReader/PrintWriter.
Avatar billede arne_v Ekspert
26. februar 2003 - 16:01 #11
For at flytte de strnge med over laver du bare et par lille utility
metoder.

private void writeln(String s) {
  toSocket.write(s.length());
  toSocket.write(s.getBytes());
  return;
}

private String readline() {
  int n = instr.read();
  byte[] temp = new byte[n];
  instre.read(temp, 0, n);
  return new String(temp);
}
Avatar billede arne_v Ekspert
26. februar 2003 - 16:02 #12
De to sidst emetoder er tastet direkte ind utestet !

Men ideen er ihvertfald rigtig.
Avatar billede repsak Nybegynder
26. februar 2003 - 16:05 #13
Ok - mit problem er bare at dette program er en chatserver/klient (lidt som MIRC). Så til at håndtere brugerenes chatbeskeder benytter jeg BufferedReader.
Er det unødvendigt? :=)
Avatar billede repsak Nybegynder
26. februar 2003 - 16:06 #14
ok du har lige svaret - tak
Avatar billede arne_v Ekspert
26. februar 2003 - 16:14 #15
Både ja og nej.

Hvis du har en helt fast protokol, således at client og server
ikke er tvivl om, hvornår de læser en streng og hvornår de læser
rå fil-data, så virker mine 2 meetoder perfekt.

open socket
write kommando
write filnavn
write fil indhold
close socket

open socket
read kommando
read filnavn
read fil indhold
close socket

er piece of cake.

Men hvis du vil veksle mellem kommandoer og fil indhold, så har
du brug for at udvide protokollen lidt.

Så skal du også sende filens længde før filen. Ellers så ved modtageren
ikke hvornår fil slutter og næste kommando starter.
Avatar billede arne_v Ekspert
26. februar 2003 - 16:17 #16
Har du overvejet at have 1 socket til at read/write kommandoer
og en anden socket til fil data ?

Så kune den første bruge BufferedReader og PrintWriter mens den
anden kunne bruge BufferedInputStream og BufferedOutputStream.
Avatar billede repsak Nybegynder
26. februar 2003 - 16:23 #17
Mange tak for dine gode input :=) Jeg arbejder videre på sagen
Avatar billede repsak Nybegynder
26. februar 2003 - 16:43 #18
Ville den bedste løsning ikke være 'at udvide protokollen' frem for at connecte 2 sockets til den samme bruger?
Avatar billede arne_v Ekspert
26. februar 2003 - 17:11 #19
Det er uden tvivl mere effektivt (køre hurtigere når det er
færdigt) at udvide protokollen.

Men det er muligvis nemmere at kode det med 2 sockets (du
bliver hurtigere færdig med programmet).

Det er et valg. Og det er svært at tale om en "bedste løsning".
Avatar billede repsak Nybegynder
08. marts 2003 - 12:19 #20
---hvor er teksten blevet af...?
Avatar billede repsak Nybegynder
11. marts 2003 - 12:57 #21
Mange tak for hjælp i trafikken
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester