[Java]Bestand oversturen via socket: wanneer EoF?

Pagina: 1
Acties:

  • RvL
  • Registratie: Maart 2002
  • Laatst online: 09:06
Hallo allemaal,

ik zit al de hele dag te zoeken naar een oplossing voor het volgende probleem. Ik een een server en een client applicatie. De Client verstuurd een bestand naar de server. Hiervoor heb ik de volgende code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public void fileSender(String fileName) {
        File file = new File(fileName);
        int intFileSize = (int) file.length();
        System.out.println("FileSize: " + intFileSize);
        String strResponse = run("sendfile_" + intFileSize);

        System.out.println(strResponse);

        if (strResponse.equals("STARTSENDING")) {
            try {
                BufferedInputStream input = new BufferedInputStream(new
                        DataInputStream(new FileInputStream(
                                file)));
                BufferedOutputStream output = new BufferedOutputStream(new
                        DataOutputStream(socSocket.
                                         getOutputStream()));
                
                byte b[] = new byte[512];
                while (input.available() > 512) {
                    input.read(b);
                    output.write(b);
                    output.flush();
                }
                //strResponse = breReceiver.readLine();
                //System.out.println("Response: " + strResponse);

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

De client verstuurd dus een commando + filesize naar de server: "SENDFILE_filesize". De server splitst dit commando, welke als string binnen komt, op in string strCommando en int fileSize. De fileSize wordt meegestuurd naar de volgende methode:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void getFile(int intFileSize) {
        try {
            File file = new File("c:/temp/newFile/small.mp3");
            BufferedInputStream  in = new BufferedInputStream(socSocket.getInputStream());
            BufferedInputStream input = new BufferedInputStream(new DataInputStream(in));
            BufferedOutputStream output = new BufferedOutputStream(new DataOutputStream(new FileOutputStream(
                    file)));
            //boolean blnTrue = true;
            while (true) {
                output.write(input.read()); 
            }
            //System.out.println(file.length());
        } catch (Exception e) {
            System.out.println("ERROR: " + e);
        }
    }

Bovenstaande methode is natuurlijk niet zo netjes (while(true)) en levert ook een foutmelding op. Namelijk, zodra de client klaar is met verzenden kapt hij er mee.

Nu zou het zo moeten zijn dat de Server na het afronden van bovenstaande methode getFile() een string "TRANSFERCOMPLETE" terug stuurt naar de client (staat in een andere methode). Om te zorgen dat deze methode uberhaupt kan eindigen had ik
Java:
1
2
3
while (true) {
                output.write(input.read()); 
            }

veranderd in
Java:
1
2
3
while (file.length() < (long)(intFileSize -1000)) {
                output.write(input.read()); 
           }

maar op een of andere manier bereikt de file die op de server weg wordt geschreven nooit de filesize van de file op de server.

Is er een makkelijkere manier om dit te doen? Ik zat zelf te denken aan iets van een EoF, maar heb geen flauw idee hoe dit aan te pakken.

Liefde maakt een smal bed breed!
Nu de dekens nog...


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:26
Ik zou sowieso van de NIO lib gebruik maken.
Misschien een nuttige link: http://javaalmanac.com/egs/java.nio/pkg.html

  • RvL
  • Registratie: Maart 2002
  • Laatst online: 09:06
Er moet toch ook een manier zijn om het op deze manier op te lossen?

Ik heb eerlijk gezegd geen tijd meer (project, slechte planning van de projectleiders, achterstand etc.) om me helemaal in de NIO lib in te lezen

Liefde maakt een smal bed breed!
Nu de dekens nog...


  • momania
  • Registratie: Mei 2000
  • Laatst online: 08:02

momania

iPhone 30! Bam!

Een filesize lijkt me sowieso overbodig... zolang er data komt, komt er data :)

Verder zou ik dit:
Java:
1
2
3
4
5
6
7
byte b[] = new byte[512]; 

while (input.available() > 512) { 
  input.read(b); 
  output.write(b); 
  output.flush(); 
} 

Vervangen door:
Java:
1
2
3
4
5
6
byte b[] = new byte[512]; 

while (input.read(b) != -1) { 
  output.write(b); 
  output.flush(); 
} 

de read() method blijft nml. gewoon lezen tot er een -1 terug komt. De -1 betekend hier EOF :)

Voor het lezen van je bestand bij je server zal je dus ook even een byte[] als buffertje moeten maken en die meegeven in je read method();

Dus geen:
Java:
1
2
3
while (true) { 
  output.write(input.read());  
} 

want nu lees je byte voor byte, aangezien de read() method maar 1 byte terug geeft :)

maar:
Java:
1
2
3
4
5
6
byte b[] = new byte[512]; 

while (input.read(b)) { 
  output.write(b);  
} 
output.flush();

Neem je whisky mee, is het te weinig... *zucht*


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 06-05 18:23

Robtimus

me Robtimus no like you

momania schreef op woensdag 15 juni 2005 @ 21:24:
Java:
1
2
3
4
5
6
byte b[] = new byte[512]; 

while (input.read(b)) { 
  output.write(b);  
} 
output.flush();
input.read(b) geeft geen boolean terug maar een int die het aantal gelezen bytes inhoudt. Dat kun je dan meteen gebruiken:
Java:
1
2
3
while ((num = input.read(b)) != -1) {
    output.write(b, 0, num);
}
Zo voorkom je dat je net wat teveel data wegschrijft als de laatste keer het array niet volledig ingelezen wordt.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • momania
  • Registratie: Mei 2000
  • Laatst online: 08:02

momania

iPhone 30! Bam!

IceManX schreef op woensdag 15 juni 2005 @ 21:30:
[...]
input.read(b) geeft geen boolean terug maar een int die het aantal gelezen bytes inhoudt.
mmm, dat had ik in het eerste voorbeeld ook wel gebruikt.. maar het idee was duidelijk dacht ik ;)

Neem je whisky mee, is het te weinig... *zucht*


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 05-05 22:23
momania schreef op woensdag 15 juni 2005 @ 21:24:
Een filesize lijkt me sowieso overbodig... zolang er data komt, komt er data :)
Mja, maar hoort die data nog bij het bestand?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Of een bestand met heel veel null-en in het midden...

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
farlane schreef op donderdag 16 juni 2005 @ 11:37:
[...]


Mja, maar hoort die data nog bij het bestand?
Er gaat iets fout (of niet 100% naar verwachting), maar precies de lengte pakken voor je bestand is niet de oplossing. Het einde van de stream mag je gewoon niet negeren.
Verwijderd schreef op donderdag 16 juni 2005 @ 12:09:
Of een bestand met heel veel null-en in het midden...
Wat er gelezen wordt maakt niet uit, als je maar geen fouten maakt als minder/meer kopieren dan er in je buffer zit oid.

Een stream is een stream.

[ Voor 3% gewijzigd door Voutloos op 16-06-2005 12:17 ]

{signature}

Pagina: 1