[JAVA] Waar komen die spaties vandaan?!

Pagina: 1
Acties:

  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Volgende probleem:

Ik heb een hele simpele http-server gemaakt. Deze leest een bestand karakter voor karakter uit en schrijft deze naar de client (browser). Echter bij dit wegschrijven wordt tussen ieder ingelezen karakter een spatie geplaatst. Hierdoor herkent de browser de html tags natuurlijk niet.

De output is dan zoiets als:

< h t t p > < b o d y .... enzovoort...

Help!?

Ow ja, hier de code:

PHP:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.io.*;
import java.net.*;
import java.util.*;

public class httpserver{  
   
    public static void main(String[] args ) {
        
    try {  
    
         // open serversocket op poort 1234
         ServerSocket s = new ServerSocket(1234);

         // wachten op connectie met de client
         Socket incoming = s.accept();

         BufferedReader br =
           new BufferedReader(
             new InputStreamReader( incoming.getInputStream() ) );
         PrintWriter out =
           new PrintWriter( incoming.getOutputStream(), true );
         System.out.print("Client gehoord, type STOP om server te sluiten");
           
         String str = br.readLine();

         StringTokenizer tokens = new StringTokenizer(str);
         
         tokens.nextToken();  String cmd=tokens.nextToken();
         
         FileInputStream fin = new FileInputStream(cmd);    
         Int i;
         
          do{ 
            i=fin.read(); 
            out.println((char)i); 
            }while(i != -1); 
        
            fin.close(); 
            fin=null; 

            // sluit de socket
            incoming.close();
      }
      catch ( Exception e ) 
      {  System.out.println( e );
      } 
   } 
}

[ Voor 62% gewijzigd door WiseGuy! op 19-03-2004 14:41 ]

we only make way for the man who boldly pushes past us


  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 27-05 12:36
In plaats van println(char) gewoon print ?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
Java codeert karakters in 16-bits waarden (UCS-2, geloof ik) en alle 'normale' letters en cijfers nemen dan ook twee bytes in beslag. Je kan probleem op twee manieren oplossen. De makkelijkste manier is om op te geven dat je document in UCS-2 gecodeerd is; je browser zou 'm dan goed moeten interpreteren. Een betere manier is om de tekst eerst te coderen in UTF-8 formaat (zodat de meeste karakter gewoon 1 byte beslaan) en dan ook de codering van je document in te stellen op UTF-8. Tenslotte kun je nog kiezen voor een specifieke (extended) ASCII codering maar daar zou ik me eigenlijk het nut niet van kunnen voorstellen; dan kun je net zo goed direct UTF-8 gebruiken.

[ Voor 4% gewijzigd door Soultaker op 19-03-2004 15:00 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Staat die html-code zo in je browser-scherm of in de daadwerkelijke source?

Ik gok op het eerste en dat je bent vergeten te kijken wat de precieze source is en je dan ziet dat het eigenlijk allemaal tekens op een losse regel zijn -> Zie Eskimootje

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
Waarom hebben jullie het over newlines? Daar heeft het probleem toch niets mee te maken?

Wat je wel zou kunnen verifiëren is dat die 'spaties' feitelijk geen spaties (ASCII 32h) maar 0-karakters zijn (00h), met behulp van een hex-editor.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Een newline in html ziet er uit als een spatie in de browser.

Als hij elk karakter apart dmv println (printline) uitspuugt:
do{
            i=fin.read();
            out.[b]println[/b]((char)i);
            }while(i != -1); 

Dan kan dat er dus in een browser uitzien alsof er heel veel spaties zijn, terwijl het eigenlijk gewoon newlines zijn, ik geloof dat ik dat moet kunnen illustreren (niks met html te maken, wel met nobr):
e e n s t u k j e

[ Voor 9% gewijzigd door ACM op 19-03-2004 15:52 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op 19 maart 2004 @ 15:31:
Waarom hebben jullie het over newlines? Daar heeft het probleem toch niets mee te maken?

Wat je wel zou kunnen verifiëren is dat die 'spaties' feitelijk geen spaties (ASCII 32h) maar 0-karakters zijn (00h), met behulp van een hex-editor.
De standaard charset van een outputstream is geloof ik gewoon (extended) ascii. (de hebben het overigens over "The operating system native charset"). Ik heb nog nooit meegemaakt dat als ik een String over een Socket verstuurde dat het er aan het eind als unicode uitkwam

[ Voor 7% gewijzigd door .oisyn op 19-03-2004 15:48 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Volgens mij is het veel effecienter om het zo te doen:
Java:
1
2
3
int size = fin.available();
byte[] bytes = new byte[size];
fin.read(bytes);


Dan kan je die array in 1 keer naar je client schrijven in plaats van byte voor byte. Als je ook grote files wilt gaan behandelen, dan moet je maar de size limiten tot 1024 of een veelvoud daarvan ofzo, en pas als je dat doet een loop maken.

"Beauty is the ultimate defence against complexity." David Gelernter


  • raoulduke
  • Registratie: Oktober 2003
  • Niet online

raoulduke

Get in!

eskimootje heeft de oplossing, goed gezien trouwens! In de browser zie je ze als spaties, omdat het gewoon nutteloze whitespace is, maar in de source staan newlines. Probleem opgelost :)

Remember, if you have any trouble you can always send a telegram to the Right People.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 26-05 23:14
Ach ja, Eskimootje en ACM hebben gewoon gelijk. Never mind me. ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

Macros schreef op 19 maart 2004 @ 16:08:
Volgens mij is het veel effecienter om het zo te doen:
Java:
1
2
3
int size = fin.available();
byte[] bytes = new byte[size];
fin.read(bytes);
als je die allocatie elke iteratie doet zal het zo efficient niet zijn. Maak die array voor je loop van een vaste grootte, en lees/schrijf dan vervolgens steeds het minimum van array.length en fin.available ()

(nog beter is natuurlijk het gebruik van de classes in java.nio)

[ Voor 7% gewijzigd door .oisyn op 19-03-2004 16:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

.oisyn schreef op 19 maart 2004 @ 16:28:
[...]


als je die allocatie elke iteratie doet zal het zo efficient niet zijn. Maak die array voor je loop van een vaste grootte, en lees/schrijf dan vervolgens steeds het minimum van array.length en fin.available ()
Dat zei ik toch, alleen ik zei het anders :p

"Beauty is the ultimate defence against complexity." David Gelernter


  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Hmn,

Het lijkt erop dat het zoiets moet zijn als Eskimootje zegt.

Als ik het volgende probeer:

PHP:
1
2
3
4
do{ 
            i=fin.read(); 
            out.print((char)i); 
            }while(i != -1);


Gebeurt er niets, alleen een melding dat ie de server niet kan vinden.

Als ik dit probeer:

PHP:
1
2
3
4
 do{ 
            i=fin.read(); 
            System.out.print((char)i); 
            }while(i != -1);


Krijg ik de inhoud van het bestand wél op m'n dosbox (server scherm) in het goede formaat....

Hoe kan dát nou weer?

we only make way for the man who boldly pushes past us


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Misschien moet je die PrintWriter eerst even flushen? Gebruik anders direct die OutputStream die je kreeg van de Socket ipv. er eerst een Writer erover te gooien, anders had je net zo goed een FileWriter kunnen gebruiken.

"Beauty is the ultimate defence against complexity." David Gelernter


  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Macros schreef op 19 maart 2004 @ 19:11:
Misschien moet je die PrintWriter eerst even flushen? Gebruik anders direct die OutputStream die je kreeg van de Socket ipv. er eerst een Writer erover te gooien, anders had je net zo goed een FileWriter kunnen gebruiken.
Ik heb 'out' geflushed voordat ik ging printen. Dat hielp niet...

Dat laatste snap ik niet helemaal.

we only make way for the man who boldly pushes past us


  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 27-05 12:36
do{
i=fin.read();
out.println((char)i);
}while(i != -1);

out.flush();


dat nadat je alles hebt toegevoegd.

[ Voor 60% gewijzigd door Eskimootje op 19-03-2004 19:46 ]


  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Eskimootje schreef op 19 maart 2004 @ 19:45:
do{
i=fin.read();
out.println((char)i);
}while(i != -1);

out.flush();


dat nadat je alles hebt toegevoegd.
_/-\o_

bedankt, dit was em...

Nu nog één dingetje.. Zogauw de waarde -1 bereikt wordt en dus feitelijk EOF stopt ie. Hij print alleen wel de waarde -1 en dat is een vraagteken. Hoe voorkom ik dit?

we only make way for the man who boldly pushes past us


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 21:44

Robtimus

me Robtimus no like you

Loop "omdraaien": van do-while naar while-do

Dus niet
Java:
1
2
3
4
5
i=fin.read();
out.println((char)i);
}while(i != -1);

out.flush();
maar
Java:
1
2
3
4
5
i = fin.read();
while (i != -1) {
    out.println((char)i);
    i = fin.read();
}
of de korte vorm:
Java:
1
while ((i = fin.read()) != -1) out.println((char)i);

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


  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Ik snap er nu helemaal geen r**t meer van. Gisteren gecompileerd en gedraaid. Perfect. Vandaag weer gedraaid, doet ie het niet meer....

De functie zelf doet het prima, want als ik naar System.out wil schrijven doe ie het wel.. Alleen als ik naar out wil schrijven gaat het mis..

Help!

PHP:
1
2
3
4
5
6
7
8
9
10
        int i;
         
        i = fin.read(); 
        
        while (i != -1) { 
            out.print((char)i); 
            i = fin.read(); 
        }
         
        out.flush();


Ik zie het niet meer!

we only make way for the man who boldly pushes past us


  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 27-05 12:36
Uhm doe eens de hele source hier neer zetten en zorg voor de juiste tag (code = java) niet php

  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.*;
import java.net.*;
import java.util.*;

public class httpserver{  
   
    public static void main(String[] args ) {
        
    try {  
    
        // open serversocket op poort 1234
        ServerSocket s = new ServerSocket(1234);

        // wachten op connectie met de client
        Socket incoming = s.accept();

        BufferedReader br =
          new BufferedReader(
            new InputStreamReader( incoming.getInputStream() ) );
        PrintWriter out =
          new PrintWriter( incoming.getOutputStream(), true );
        System.out.println("Client gehoord");
           
        String str = br.readLine();
        System.out.println("1");
        StringTokenizer tokens = new StringTokenizer(str);
        System.out.println("2"); 
        tokens.nextToken();  String cmd=tokens.nextToken();
        System.out.println("3");
        FileInputStream fin = new FileInputStream(cmd);    
        System.out.println("4");
        int i;

        i = fin.read(); 

        while (i != -1) { 
            out.print((char)i); 
            i = fin.read(); 
        }

        out.flush();
            
        fin.close(); 

        fin=null; 
        
        incoming.close();

      }
      catch ( Exception e ) 
      {  System.out.println( e );
      } 
   } 
}


Dit is 'em.. Nog een vraag. Hoe zet ik de root voor de serversocket? Als ik de server nu start en een bestand opvraag, kijkt ie op c:\ terwijl ik vanuit een andere directory start. Deze directory moet ook de root worden.

we only make way for the man who boldly pushes past us


  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 27-05 12:36
Weet je zeker dat er wel het goede in de variabele cmd komt te staan, daarnaast zijn je debug regels niet echt overduidelijk (1, 2, 3, 4) en de root kun je maken door een static string te defineren met de dir en deze voor alles te plakken wat je opent.

  • WiseGuy!
  • Registratie: Juni 2003
  • Laatst online: 18:47
Eskimootje schreef op 21 maart 2004 @ 22:01:
Weet je zeker dat er wel het goede in de variabele cmd komt te staan, daarnaast zijn je debug regels niet echt overduidelijk (1, 2, 3, 4) en de root kun je maken door een static string te defineren met de dir en deze voor alles te plakken wat je opent.
Ja, de goede waarde staat er wel in... Als ik vanuit de browser een niet bestaand bestand wil openen, komt m'n fileinputstream met de melding dat het bestand niet bestaat... Dus daar ligt het probleem denk ik niet.

we only make way for the man who boldly pushes past us


  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 27-05 12:36
Nou dan moet je nog een kijken want als ik gewoon een directe path opgeef in het programma doet hij het wel.

[ Voor 3% gewijzigd door Eskimootje op 22-03-2004 09:49 ]


Verwijderd

Vraagje: waarom chars wanneer je ook met bytes kunt werken? Als je source-file goed is, moet dit ook goed gaan eigenlijk. Of ben ik nou weer onzinnig bezig? (heb het topic niet helemaal goed gelezen...)

Java:
1
2
3
4
5
6
        byte[] bytes = new byte[65536];
        int readBytes = fis.read(bytes);
        while (readBytes > -1) {
          fos.write(bytes, 0, readBytes);
          readBytes = fis.read(bytes);
        }

Toelichting: fis is een FileInputStream en fos is een FileOutputStream.

Bovendien heb je geen root voor je server socket. Maar kijk eens naar de constructors van FileInputStream en File, misschien dat je daar verder mee komt.
Pagina: 1