[JAVA] chars, bytes en bestanden

Pagina: 1
Acties:
  • 117 views sinds 30-01-2008
  • Reageer

  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Ik ben nog steeds met mijn puzzel bezig...
Ik schrijf boolean[] naar disk, maar vorm ze eerst om naar bits (byte), die door omzetting naar char[] in een StringBuffer kunnen worden gedumpt.
Dit werkt super.
Maar nu wil ik de StringBuffer tijdelijk op schijf zetten en daarna weer teruglezen.
Dus:

input:
byte bijt, bijt2, bijt3, bijt4;
bijt1 = 58
bijt2 = 216
bijt3 = 0
bijt4 = 0

Dit worden dan chars, namelijk:
58, -40, 0 en 0.
Maar als ik dit in een StringBuffer prop en deze op disk zet met een FileWriter (write(char[]) of write(StringBuffer.toString()).
En daarna lees ik ze terug met een FileReader
read(int).
Dan krijg ik dus de volgende cijfers terug:
58, 63, 0, 0.

Waarom is mijn -40 (oorspronkelijk 216 = 11011000) nu ineens 63 geworden (00111111).

Want nu is mijn oorspronkelijk array
11011000 verandert in
00111111

Hoe kan dit ????

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • im_ik
  • Registratie: November 2000
  • Laatst online: 28-12-2025

im_ik

dat ben ik dus

Dit heeft met sign'ed byte te maken...
OFte wel
1 byte kan van -127 tot +127 gaan
of van 0 tot 255.
Ik denk dat je hierin het probleem moet zoeken....
Maar hoe dat te doen in java ....ik ni weet.( en geen tijd om te zoeken, ben nog aan het overwerken :(

edit: Wat staat er in je file op disk ??

Atari Terminator AI - LegoBlockX3 = ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.T008ᖟ


  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
ff zo vrij geweest om snel een demo (compileerbaar) progje in elkaar te flansen...
code:
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
55
56
57
58
59
import java.io.*;

public class test
{
    public test()
    {
    }

    public void start()
    {
      byte bijt1, bijt2, bijt3, bijt4;
      bijt1 = (byte)58;
      bijt2 = (byte)216;
      bijt3 = (byte)0;
      bijt4 = (byte)0;
      char[] kars = new char[4];
      kars[0] = (char)bijt1;
      kars[1] = (char)bijt2;
      kars[2] = (char)bijt3;
      kars[3] = (char)bijt4;
      StringBuffer sb = new StringBuffer();
      sb.append( kars );
      System.out.println( "Voor schrijven naar disk" );
      System.out.println( (byte)sb.charAt(0) );
      System.out.println( (byte)sb.charAt(1) );
      System.out.println( (byte)sb.charAt(2) );
      System.out.println( (byte)sb.charAt(3) );
      try {
        FileWriter out = new FileWriter( "test.tst" );
        out.write( sb.toString() );
        out.close();
        FileReader in = new FileReader( "test.tst" );
        char[] diskChars = new char[4];
        in.read( diskChars, 0, 4 );
        in.close();
        sb = null;
        sb = new StringBuffer();
        sb.append( diskChars );
        System.out.println( "" );
        System.out.println( "Na schrijven naar disk" );
        System.out.println( (byte)sb.charAt(0) );
        System.out.println( (byte)sb.charAt(1) );
        System.out.println( (byte)sb.charAt(2) );
        System.out.println( (byte)sb.charAt(3) );
        System.out.println( "" );
        System.out.println( "Waarom is '-40' nu '63' geworden??" );
      } catch (Exception e)
      {
        System.out.println( "Oeps... " + e );
      }

    }

    static void main (String args[])
    {
      test me = new test();
      me.start();
    }
}

M'n byte begint z'n leven als 216. Prima. Dan wordt het een char en verandert ie in -40. Geen probleem, want dat is binair hetzelfde (-40 + 256 = 216). Dan schrijven naar disk en teruglezen en voila: 63 :(

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Op woensdag 13 juni 2001 21:34 schreef im_ik het volgende:
...
edit: Wat staat er in je file op disk ??
Hoe kijk ik in hex in een bestand ??
Heeft w2k wel een hex-editor... ??

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • a3konijn
  • Registratie: Oktober 2000
  • Laatst online: 26-08 19:21
Ik heb effe zitten testen, maar alle waarden boven de 127 worden als 63 teruggegeven. Dit is het resultaat als ik 126, 127, 128 en 129 invul bij bijt1 - bijt4

Afbeeldingslocatie: http://members.brabant.chello.nl/~a.wisse1/a3/dos.gif

Dus het heeft toch met het feit te maken dat Java standaard een signed byte/char pakt en die lopt van -127 tot 128 alleen waar die 63 dan vandaan komt??

  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Op woensdag 13 juni 2001 21:58 schreef a3konijn het volgende:
...
Dus het heeft toch met het feit te maken dat Java standaard een signed byte/char pakt en die lopt van -127 tot 128 alleen waar die 63 dan vandaan komt??
...
Ligt het aan de FileReader of aan de FileWriter ??

Ik heb al 6 pogingen gedaan om hexeditors te downen :(
Eentje .SIS extensie (welk programma is dat nou weer)
eentje werkt niet onder 2000, maar alleen onder DOS/w95

Ik ben dus wel benieuwd wat er in het bestand staat...

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Gevonden.
code:
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
import java.io.*;

public class test
{
    public test()
    {
    }

    public void start()
    {
      byte bijt1, bijt2, bijt3, bijt4;
      bijt1 = (byte)58;
      bijt2 = (byte)216;
      bijt3 = (byte)0;
      bijt4 = (byte)0;
      char[] kars = new char[4];
      kars[0] = (char)bijt1;
      kars[1] = (char)bijt2;
      kars[2] = (char)bijt3;
      kars[3] = (char)bijt4;
      StringBuffer sb = new StringBuffer();
      sb.append( kars );
      System.out.println( "Voor schrijven naar disk" );
      System.out.println( (byte)sb.charAt(0) );
      System.out.println( (byte)sb.charAt(1) );
      System.out.println( (byte)sb.charAt(2) );
      System.out.println( (byte)sb.charAt(3) );
      byte[] test2;
      test2 = sb.toString().getBytes();
      System.out.println( "Voor schrijven naar disk, conversie vanuit StringBuffer" );
      System.out.println( test2[0] );
      System.out.println( test2[1] );
      System.out.println( test2[2] );
      System.out.println( test2[3] );
      char[] test3 = new char[4];
      sb.getChars(0, 4, test3, 0);
      System.out.println( "Voor schrijven naar disk, conversie met sb.getChars" );
      System.out.println( (byte)test3[0] );
      System.out.println( (byte)test3[1] );
      System.out.println( (byte)test3[2] );
      System.out.println( (byte)test3[3] );
    }

    static void main (String args[])
    {
      test me = new test();
      me.start();
    }
}

OK, waarom doet Java dit ??
Conversie van StringBuffer via String naar bytes geeft een verkeerd resultaat.
Conversie van StringBuffer via chars naar bytes geeft een goed resultaat.

Waarom ??
Wie heeft een oplossing.... ??

Edit: kan ik een ByteArrayOutputStream en ByteArrayInputStream kunnen gebruiken ??

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Hmm... code aangepast naar het volgende.
Blijft natuurlijk raar van die 63 in de StringBuffer naar String....
code:
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
55
56
57
import java.io.*;

public class test
{
    public test()
    {
    }

    public void start()
    {
      byte bijt1, bijt2, bijt3, bijt4;
      bijt1 = (byte)58;
      bijt2 = (byte)216;
      bijt3 = (byte)0;
      bijt4 = (byte)0;

      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      buffer.write( bijt1 );
      buffer.write( bijt2 );
      buffer.write( bijt3 );
      buffer.write( bijt4 );
//    buffer.close();

      byte[] test;
      test = buffer.toByteArray();
      System.out.println( (byte) test[0] );
      System.out.println( (byte) test[1] );
      System.out.println( (byte) test[2] );
      System.out.println( (byte) test[3] );

      try {
        FileOutputStream out = new FileOutputStream( "test.tst" );
        buffer.writeTo( out );
        out.close();
        FileInputStream in = new FileInputStream( "test.tst" );
        byte[] test2 = new byte[4];
        in.read( test2 );
        in.close();
        System.out.println( "Na herinlezen" );
        System.out.println( (byte) test2[0] );
        System.out.println( (byte) test2[1] );
        System.out.println( (byte) test2[2] );
        System.out.println( (byte) test2[3] );
      } catch (Exception e)
      {
        System.out.println( "oeps: " + e );
      }


    }

    static void main (String args[])
    {
      test me = new test();
      me.start();
    }
}

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Kan je niet voor het schrijven, van je byte 128 aftrekken en na het lezen er weer 128 bij tellen?

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#28344
4.2.1 Integral Types and Values
The values of the integral types are integers in the following ranges:

For byte, from -128 to 127, inclusive
For short, from -32768 to 32767, inclusive
For int, from -2147483648 to 2147483647, inclusive
For long, from -9223372036854775808 to 9223372036854775807, inclusive
For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535
Denk er even aan dat Java Unicode gebruikt.
Probeer die bytes is te vervangen door unsigned shorts.

Een char is 2 bytes lang. In weze een unsigned short in Java.

Probeer maar is.


Waarschijnlijk gaat het mis op het moment dat je je chars weer terug cast naar bytes.

Als je gaat casten moet je altijd oppassen voor dit soort dingen. De upcast van byte naar char zal wel goed gaan, maar de downcast van char naar byte. Oei oei oei....


Nogmaal een char is geen byte.
Een char is een unsigned short, en da's twee bytes.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Dit is trouwens een perfect voorbeeld van een van de grootste problemen van ouwderwetse C en C++ programmeurs die onder met Unicode gaan werken.

De definitie van een karakter is een byte zit zo diepgeworteld. Maar bij Unicode is dat NIET het geval. :)

Mooi onderzoeksprojectje dit. Is didactisch zeer grappig. :P

Verwijderd

Op woensdag 13 juni 2001 23:26 schreef The - DDD het volgende:
Dit is trouwens een perfect voorbeeld van een van de grootste problemen van ouwderwetse C en C++ programmeurs die onder met Unicode gaan werken.

De definitie van een karakter is een byte zit zo diepgeworteld. Maar bij Unicode is dat NIET het geval. :)

Mooi onderzoeksprojectje dit. Is didactisch zeer grappig. :P
Java werkt per definitie met unicode! ;)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op woensdag 13 juni 2001 23:27 schreef joska het volgende:

[..]

Java werkt per definitie met unicode! ;)
Precies, erg lastig om aan te leren als je net een half jaar/jaar in C/C++/Pascal/whatever er van overtuigd bent geraakt dat een char altijd 1 byte is. :)

Verwijderd

Op woensdag 13 juni 2001 23:30 schreef The - DDD het volgende:

[..]

Precies, erg lastig om aan te leren als je net een half jaar/jaar in C/C++/Pascal/whatever er van overtuigd bent geraakt dat een char altijd 1 byte is. :)
Ik heb het aan der lijve ondervonden! :)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op woensdag 13 juni 2001 23:33 schreef joska het volgende:

[..]

Ik heb het aan der lijve ondervonden! :)
Waarom voel ik in eenkeer een vlaag van herkenning :?

Verwijderd

Op woensdag 13 juni 2001 23:36 schreef The - DDD het volgende:

[..]

Waarom voel ik in eenkeer een vlaag van herkenning :?
Kweenie? Omdat je pascal/c programmeur was en toen kennis maakte met Java? :)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ben nog redelijk nat achter de oortjes hoor (3de jaar HI). Maar ik rotzooi al behoorlijk lang in verschillende talen..

Ben m'n eerste taal inmiddles al weer verleerd, basic op de ZX-Spectrum..

Stringetjes printen tot je een ons woog. Jaja!!

(ben nu 21)

Maar laten we niet teveel OT klatsen. Het is geen Kroeg hier. :) M.a.w.: Hoe gaat het er mee?? (just kidding) ;) :P

Verwijderd

Op woensdag 13 juni 2001 23:41 schreef The - DDD het volgende:
Ben nog redelijk nat achter de oortjes hoor (3de jaar HI). Maar ik rotzooi al behoorlijk lang in verschillende talen..

Ben m'n eerste taal inmiddles al weer verleerd, basic op de ZX-Spectrum..

Stringetjes printen tot je een ons woog. Jaja!!

(ben nu 21)
Aaaah! basic:
10 print "Hoi"
20 goto 10
:)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op woensdag 13 juni 2001 23:42 schreef joska het volgende:

[..]

Aaaah! basic:
10 print "Hoi"
20 goto 10
:)
Nee meer:

10 print "Jasper is een etter"
20 goto 10

Liefst als hij (m'n broer) dan net met de ZX bezig wou. Hij wist hoe hij manic miner en jetset moest laden van tape. Maar meer ook niet.

Verwijderd

Op woensdag 13 juni 2001 23:45 schreef The - DDD het volgende:

[..]

Nee meer:

10 print "Jasper is een etter"
20 goto 10

Liefst als hij (m'n broer) dan net met de ZX bezig wou. Hij wist hoe hij manic miner en jetset moest laden van tape. Maar meer ook niet.
Naughty boy! :)

  • im_ik
  • Registratie: November 2000
  • Laatst online: 28-12-2025

im_ik

dat ben ik dus

Op woensdag 13 juni 2001 22:48 schreef GarBaGe het volgende:
Hmm... code aangepast naar het volgende.
Blijft natuurlijk raar van die 63 in de StringBuffer naar String....
[
63 = ?

Ik denk dat de programeur van java deze hebben ingebouwt aangezien je char allen van 0-127 lopen.
Krijgen je in de string een '?'

Atari Terminator AI - LegoBlockX3 = ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.T008ᖟ


Verwijderd

Op woensdag 13 juni 2001 23:49 schreef im_ik het volgende:

[..]

63 = ?

Ik denk dat de programeur van java deze hebben ingebouwt aangezien je char allen van 0-127 lopen.
Krijgen je in de string een '?'
Nee, het kenmerk van unicode is juist dat die meer dan 1 byte is!

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op woensdag 13 juni 2001 23:49 schreef im_ik het volgende:

[..]

63 = ?

Ik denk dat de programeur van java deze hebben ingebouwt aangezien je char allen van 0-127 lopen.
Krijgen je in de string een '?'
char 's lopen in Java dus van 0 t/m 65535..

Altijd lachen die programmeurs met hun heilige char == byte link :)

Verwijderd

Op woensdag 13 juni 2001 23:58 schreef The - DDD het volgende:

[..]

char 's lopen in Java dus van 0 t/m 65535..

Altijd lachen die programmeurs met hun heilge char == byte link :)
C nodigt nou eenmaal uit tot slordig programmeren! :)

  • GarBaGe
  • Registratie: December 1999
  • Laatst online: 06-09 16:02
Leuke is dat ik dus nog veel minder C programmeer dan Java. Ik wist helemaal niet dat in C een byte gelijk is aan een char :)

Ik heb gewoon een rijtje bits (boolean[]) die is wilde opslaan in het geheugen en op de schijf als bits. Het leek me logisch om daarvoor een byte te gebruiken.
Echter de array van bytes die dan ontstaat moet wel super-dynamisch zijn. Oftewel toevoegen en verwijderen, zonder steeds een nieuw array aan te moeten maken met een andere lengte en dan iedere keer het ene array naar de nieuwe te copieren.
Daarvoor wilde ik eerst een String gebruiken. Dat is makkelijk editen...
Maar met 2000-3000 tekens werd een String vreselijk traag. Zo ben ik bij een StringBuffer aangekomen. Die was dus veel sneller, maar daar kon je weer geen bytes instoppen, maar chars. Dus ik denk ik cast de bytes gewoon tot chars en later als ik ze eruit vis, dan cast ik ze weer terug naar bytes. Dat heb ik getest en dat werkt goed.
StringBuffer is echt lekker snel...

Maar nu wilde ik de StringBuffer op schijf zetten. Dus ik denk: StringBuffer.toString(). Maar nu blijkt de conversie dus niet goed te gaan...
Dus nu gebruik ik maar een ByteArrayOutputStream...

Dat een byte 8 bits was, had ik wel door. Maar wat een char was... Ik heb geen flauw idee :)
Leuk om te weten dat chars dus unicode zijn...

Ryzen9 5900X; 16GB DDR4-3200 ; RTX-4080S ; 7TB SSD


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

The - DDD zei laatst:
char 's lopen in Java dus van 0 t/m 65535..

Altijd lachen die programmeurs met hun heilige char == byte link :)
Programmeurs leggen die link altijd, idd. Maar dat is dom, want een byte is in feite gewoon een lengte-aanduiding. Hoeveel bits heeft een character in C? idd, 8, dus is het 1 byte "lang". Maar in Java dus 16, dus is het 2 bytes "lang".

Trouwens is dit ook controversieel, want het char-type wordt in de oude std library van C zoveel mogelijk vermeden.
zie functies als getchar, enzo. Die geven geen char terug maar een int (ook weer 16 bits)

Heerlijk die "standaarden" ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1