/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Datatyper i java
Fra : Brian Johansen


Dato : 03-05-04 08:07

Hej Alle !

Jeg har oprindeligt implementeret en protokol i c vha. en kombination af
struct og union, og undrer hvordan man nemmest og bedst implementerer
samme i Java.

Brugen er som følger:

struct {
   BYTE RequestCode;

   union {
      BYTE dataBuffer[32];
      
      struct {
         BYTE num;
         int val1;
         float val2
         unsigned long val3;
      } req1;
   } u;
} RxProtocol;

Ideen er at man fylder data ind i RxProtocol.u.dataBuffer (f.eks.
serielle bytes fra et embedded system). I byte strømmen kan man så pille
req1 struct data ud som f.eks. RxProtocol.u.req1.val2, en meget nem måde
at hente formateret data ud af en simpel buffer.

Jeg er ny mht. Java, og kan ikke rigtig se hvordan jeg kan opnå samme i
Java ??? Nogen der har gode ideer ??


Mvh.

Brian

 
 
Thorbjoern Ravn Ande~ (03-05-2004)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 03-05-04 08:27

Brian Johansen <__BRJ@brijo.dk> writes:

> Jeg er ny mht. Java, og kan ikke rigtig se hvordan jeg kan opnå samme
> i Java ??? Nogen der har gode ideer ??

Du skal lave konverteringen til din datatype manuelt fra bufferens indhold.

--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk/ravn

Soren Kuula (03-05-2004)
Kommentar
Fra : Soren Kuula


Dato : 03-05-04 09:02

Thorbjoern Ravn Andersen wrote:
> Brian Johansen <__BRJ@brijo.dk> writes:
>
>
>>Jeg er ny mht. Java, og kan ikke rigtig se hvordan jeg kan opnå samme
>>i Java ??? Nogen der har gode ideer ??
>
>
> Du skal lave konverteringen til din datatype manuelt fra bufferens indhold.
>
Du implementerer en klasse til erstating for din struct, lader den
implementere java.io.Externalizable, og implementerer en passende
readExternal metode. Det ville jeg i hvert fald prøve først.

MVH
Søren

Brian Johansen (03-05-2004)
Kommentar
Fra : Brian Johansen


Dato : 03-05-04 10:06

> Du implementerer en klasse til erstating for din struct, lader den
> implementere java.io.Externalizable, og implementerer en passende
> readExternal metode. Det ville jeg i hvert fald prøve først.

Ok ! må vist hellere læse lidt på teorien. Tak for hjælpen.

Mvh.

Brian

Brian Johansen (04-05-2004)
Kommentar
Fra : Brian Johansen


Dato : 04-05-04 07:25

>> Du implementerer en klasse til erstating for din struct, lader den
>> implementere java.io.Externalizable, og implementerer en passende
>> readExternal metode. Det ville jeg i hvert fald prøve først.

hmmmm har prøvet det men gør et eller andet galt. Her er mit eksempel:

klassen Extern:

import java.io.Externalizable;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
public class Extern implements Externalizable {
private int lowBid;
private String highBid;

public Extern() {
lowBid = -1;
highBid = "none";
}
public Extern (int lowBid, String highBidData ) {
this.lowBid = lowBid;
this.highBid = highBidData;
}

public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
lowBid = in.readInt();
highBid = (String) in.readObject();
}
public void writeExternal(ObjectOutput out)
throws IOException {
out.writeInt( lowBid );
out.writeObject( highBid );
}
public String toString() {
return "low " + lowBid + " high: " + highBid;
}
}


App klassen:

import java.util.*;
import java.io.*;

public class HentOgGemData
{
public static void main(String[] arg) throws Exception
{
   Extern ex = new Extern(58, "BRJ");
   
   FileOutputStream fos = new FileOutputStream("t.tmp");
   ObjectOutputStream oos = new ObjectOutputStream(fos);

   
   ex.writeExternal(oos);

   oos.close();

   FileInputStream fis = new FileInputStream("t.tmp");
   ObjectInputStream iis = new ObjectInputStream(fis);

   ex.readExternal(iis);

   iis.close();

   System.out.println(ex.toString());
   
}
}


Eksemplet virker for så vidt, men kigger man i filen t.tmp (hex dump)
ligger der mere data end bare lowbid og highbid:

aced 0005 7704 0000 003a 7400 0342 524a ....w....:t..BRJ

Jeg havde forventet at kun 58BRJ ville ligge i filen !

Har det noget med ObjectOutputStream at gøre eller ??

Mvh.

Brian

Soren Kuula (04-05-2004)
Kommentar
Fra : Soren Kuula


Dato : 04-05-04 10:47

Hejsa,

> Jeg havde forventet at kun 58BRJ ville ligge i filen !
> Har det noget med ObjectOutputStream at gøre eller ??

JA det har det. Den har en halvavanceret måde at holde styr på kun at
skrive hvert objekt ud en gang, blandt andet. Der er vist også noget med
at komplekse typer (objeker) bliver skrevet ud på
divisible-med-et-eller-andet positioner i streamen.

Dit eksempel kan jo nærmest ikke virke på den forventede måde, for hvis
du skriver mange Strings ud efter hinanden, skal InputStreamen jo vide
hvor den ene begynder og den anden slutter.

Men du kan gøre flg. når du skriver en String (ikke testet, det er
skitse-kode :) )

String s = "gummiand";
out.writeInt(s.length()); // drop evt dette hvis dit dataformat ikke har det
for (int i=0; i<s.length(); i++) {
char aChar = s.charAt(i);
byte anISO8859Char = (byte)aChar;
out.writeByte(anISO8859Char);
}

Hvis det skal være helt rigtigt, burde du tage hensyn til tegnsættet ..
altså finde en passende encoding, og bruge de passende kodere i Writer
eller java.nio (jer er lidt hellig med at alle tegn skal være kodet
korrekt - selv kinesiske). Men hvis det bare er ASCII, kan du bruge
fuskerløsningen ovenfor med at konvertere chars lige til bytes.

Så - kort sagt - lav dit eget low level format for Strings.

Der er en anden ting - endianness !! Hvis du ved hvad det er, så ok.
Ellers får du måske en overraskelse hvis java programmet bruger readInt
til noget som den anden ende har skrevet, og du får et helt andet tal
end forventet. Det er pga rækkefølgen som bytes'ene i et langt tal
udskrives i - skal det være den mest betydende først eller den mindst
betydende ?!

MVH
Søren

Soren Kuula (04-05-2004)
Kommentar
Fra : Soren Kuula


Dato : 04-05-04 10:50

Soren Kuula wrote:
> Hejsa,
>
>> Jeg havde forventet at kun 58BRJ ville ligge i filen !
>> Har det noget med ObjectOutputStream at gøre eller ??
>
>
> JA det har det. Den har en halvavanceret måde at holde styr på kun at
> skrive hvert objekt ud en gang, blandt andet.

For ellers, hvad ville der så ske hvis man writede denne objektstruktur:

/--<--\
A B
\-->--/

(pilene er pointere)

Det bliver en lang aften ...

MVH
Søren

Brian Johansen (04-05-2004)
Kommentar
Fra : Brian Johansen


Dato : 04-05-04 12:12

Hej igen,

Det var lidt dumt af mig at medtage en string i eksemplet, det jeg
interesserer mig mest for er byte, int og long.
Men selvom jeg dropper stringen, får jeg stadig mere end bare tal i min
test fil.
I beskrivelsen af Externalizable lægger de op til, at man derigennem får
fuld kontrol over hvad der puttes ind i streamen, netop ved at definere
egne implementationer af writeExternal og ReadExternal.
Jeg kan bare ikke få det til at virke når jeg ikke bruger
ObjectOutputStream (den implementerer interfacet ObjectOutput), jeg kan
ikke bare sende streamen direkte til et filewriter objekt.

Jeg må nok lære lidt mere om teorien bag streams og deres syntax

Mvh.

Brian

Soren Kuula (04-05-2004)
Kommentar
Fra : Soren Kuula


Dato : 04-05-04 14:55

Brian Johansen wrote:

> Hej igen,
>
> Det var lidt dumt af mig at medtage en string i eksemplet, det jeg
> interesserer mig mest for er byte, int og long.
> Men selvom jeg dropper stringen, får jeg stadig mere end bare tal i
> min test fil.
> I beskrivelsen af Externalizable lægger de op til, at man derigennem
> får fuld kontrol over hvad der puttes ind i streamen, netop ved at
> definere egne implementationer af writeExternal og ReadExternal.
> Jeg kan bare ikke få det til at virke når jeg ikke bruger
> ObjectOutputStream (den implementerer interfacet ObjectOutput), jeg
> kan ikke bare sende streamen direkte til et filewriter objekt.
>
> Jeg må nok lære lidt mere om teorien bag streams og deres syntax
>
> Mvh.
>
> Brian

Oooooooooooops .. måske er det oss mig der giver rådne råd ... ja det er
vist rigtigt at ObjectOutputStream ikke er sådan at tæmme. Gad vide hvor
langt man kommer med noget andet, f. x. at man selv implementerer en
ObjectOutput som bare stejler hvis man skriver ikkesimple typer. Eller ,
hvor langt kommer man med en DataOutput(Stream) alene ?

MVH
Søren


Ulrik Magnusson (03-05-2004)
Kommentar
Fra : Ulrik Magnusson


Dato : 03-05-04 17:51



Brian Johansen wrote:

> Hej Alle !
>
> Jeg har oprindeligt implementeret en protokol i c vha. en kombination af
> struct og union, og undrer hvordan man nemmest og bedst implementerer
> samme i Java.
>
> Brugen er som følger:
>
> struct {
> BYTE RequestCode;
>
> union {
> BYTE dataBuffer[32];
>
> struct {
> BYTE num;
> int val1;
> float val2
> unsigned long val3;
> } req1;
> } u;
> } RxProtocol;
>
> Ideen er at man fylder data ind i RxProtocol.u.dataBuffer (f.eks.
> serielle bytes fra et embedded system). I byte strømmen kan man så pille
> req1 struct data ud som f.eks. RxProtocol.u.req1.val2, en meget nem måde
> at hente formateret data ud af en simpel buffer.
>
> Jeg er ny mht. Java, og kan ikke rigtig se hvordan jeg kan opnå samme i
> Java ??? Nogen der har gode ideer ??

Måske ikke verdens smukkeste og mest effektive program, men et bud:


public class RxProtocol
{
public byte RequestCode;
public Buffer u = new Buffer();


// rimelig grim klasse som udelukkende eksisterer for
// at skaffe adgang til protected variabel "buf" i
// java.io.ByteArrayOutputStream
private static class MyByteArrayOutputStream
extends
java.io.ByteArrayOutputStream
{
public MyByteArrayOutputStream( byte[] bytes )
{
buf = bytes;
}
}

// dataBuffer og tilhørende fortolkninger
private static class Buffer
{
// jeg kan kun tælle til 17 bytes - er det bare mig?
public final byte[] dataBuffer = new byte[17];
// læsning "indirekte" fra dataBuffer
private java.io.DataInputStream dataInputStream =
new java.io.DataInputStream(
new java.io.ByteArrayInputStream(dataBuffer) );

public Buffer()
{
dataInputStream.mark(dataBuffer.size());
}

public void close() throws java.io.IOException
{
dataInputStream.close();
}

public byte num() throws java.io.IOException
{
dataInputStream.reset();
return dataInputStream.readByte();
}

public int val1() throws java.io.IOException
{
dataInputStream.reset();
dataInputStream.skip(1);
return dataInputStream.readInt();
}

public float val2() throws java.io.IOException
{
dataInputStream.reset();
dataInputStream.skip(5);
return dataInputStream.readInt();
}

public long val3() throws java.io.IOException
{
dataInputStream.reset();
dataInputStream.skip(9);
return dataInputStream.readLong();
}
}

// test
public static void main( String[] args ) throws java.io.IOException
{
RxProtocol rxProtocol = new RxProtocol();
// skriv lidt testdata i dataBuffer
java.io.DataOutputStream dataOutputStream =
new java.io.DataOutputStream(
new MyByteArrayOutputStream(rxProtocol.u.dataBuffer ) );
dataOutputStream.writeByte( Byte.MAX_VALUE );
dataOutputStream.writeInt( Integer.MAX_VALUE );
dataOutputStream.writeFloat( Float.MAX_VALUE );
dataOutputStream.writeLong( Long.MAX_VALUE );
dataOutputStream.close();

// hent data ud igen
System.out.println( "num=>" + rxProtocol.u.num() );
System.out.println( "val1=>" + rxProtocol.u.val1() );
System.out.println( "val2=>" + rxProtocol.u.val2() );
System.out.println( "val3=>" + rxProtocol.u.val3() );
rxProtocol.u.close();
}

}


Brian Johansen (04-05-2004)
Kommentar
Fra : Brian Johansen


Dato : 04-05-04 07:28

ulempen ved den metode er jo at du selv skal regne ud eksakt hvor i
bufferen dine data er gemt !

Tak for dit tip.

Mvh.

Brian

Soren (Home) (07-05-2004)
Kommentar
Fra : Soren (Home)


Dato : 07-05-04 12:51

Brian Johansen <__BRJ@brijo.dk> writes:

[snip]
>
> Jeg er ny mht. Java, og kan ikke rigtig se hvordan jeg kan opnå samme i Java ???
> Nogen der har gode ideer ??

Du kan bruge et byte[] array og selv lave konverteringen til/fra .. Ikke
elegant, men f.eks. er en int jo ikke det samme i Java og C, saa du maa
selv staa for det hele.


Mvh,



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408918
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste