Avatar billede anadan Nybegynder
05. februar 2003 - 08:26 Der er 24 kommentarer og
1 løsning

InputStream buffer

Jeg har en Socket forbindelse der skal læse nogle bytes fra "den anden side". Jeg bruger socket.getInputStream().read(buffer) og ved ikke hvor meget data jeg modtager hver gang. Jeg ønsker at have så lille en buffer størrelse som muligt, og om nødvendigt læse ind fra streamen flere gange for det samme datasæt. Jeg har prøvet med available(), men ved afsending af en 10000 byte stream returnerede available kun 4380... Nogen løsninger?
Avatar billede arne_v Ekspert
05. februar 2003 - 09:23 #1
Read returnerer hvor mange bytes den har læst !
Avatar billede arne_v Ekspert
05. februar 2003 - 09:25 #2
InputStream is = socket.getInputStream();
int l;
byte[] b = new byte[10000];
while((l = is.read(b)) >= 0) {
  System.out.println(l + " bytes read to buffer");
}
Avatar billede arne_v Ekspert
05. februar 2003 - 09:26 #3
read returnerer -1 hvis der ikke er mere data.
Avatar billede anadan Nybegynder
05. februar 2003 - 09:32 #4
Problemet er også at jeg skal vide hvor mange bytes der kommer i alt, da jeg skal smide det hele sammen i ét stort array, som jeg skal have dekrypteret. Det ville være rart at kunne lave det array efter første indlæsning og så System.arraycopy dem sammen i det store array
Avatar billede arne_v Ekspert
05. februar 2003 - 09:38 #5
Det kan ikke generelt lade sig gøre.

Men det kan lade sig gøre i visse tilfælde.

Hvis f.eks. du har kontrol over programmet i den anden ende
og det ved hvormange bytes det vil sende, så kan du jo lave
en lille protokol der hedder, at først sendes 4 bytes med længden af
data og så sendes data selv.
Avatar billede anadan Nybegynder
05. februar 2003 - 13:15 #6
Jeg synes det er en halv løsning
Avatar billede arne_v Ekspert
05. februar 2003 - 13:34 #7
Nok muligt - men det er den *eneste* løsning !

Når dit "read program" laver en read så kan det jo ikke vide:
  - om der er data undervejs
  - om "send program" i den anden ende vil sende flere data

Derfor er der ikke nogen generel måde at få at vide, hvor meget
data der kommer ialt på en given socket.

Det skal bygges ind i den protokol der ligger oven på sockets.

Og jeg er kommet med et simpelt forslag til et sådant.
Avatar billede arne_v Ekspert
05. februar 2003 - 13:49 #8
Begge min svar:
  - at read returnerer antal læste bytes
  - at det ikke er muligt at vide hvormange bytes der kommer ialt
er korrekte.
Avatar billede anadan Nybegynder
05. februar 2003 - 13:51 #9
Det kan godt være at svarene er korrekte, men en halv (omend eneste løsning) løser ikke mit problem
Avatar billede arne_v Ekspert
05. februar 2003 - 13:59 #10
Hvad vil have ?  Vi kan jo ikke løse et uløseligt problem !

Jeg kan kun se, at har 2 praktiske muligheder:
1)  allokere en buffer du er sikker på er stor nok til din
    problem-stilling
2)  lade "send program" sende længden af data inden selve data

Vi kan hjælpe dig med kode til dette.

Men vi kan ikke udrette mirakler.
Avatar billede anadan Nybegynder
05. februar 2003 - 14:21 #11
Jeg har overvejet dine forslag som mulige løsninger, men hvis de ikke løser mit problem, kan jeg ikke se hvorfor jeg skal acceptere dine svar, medmindre du bare vil have de point...
Avatar billede arne_v Ekspert
05. februar 2003 - 15:01 #12
Det er dit valg om du vil give point.

Der er mange som giver point også for "det kan ikke lade sig gøre svar".
Avatar billede =maddog= Nybegynder
05. februar 2003 - 17:09 #13
Jeg lavede engang et forsøg hvor jeg prøvede hvor mange bytes der blev læst før streamen missede og skulle genstartes med en HTTP request. Det var mærkværdigvis et relativt lavt tal og jeg valgte en lille buffer (300 bytes) på det grundlag.
Husk at give din buffer en god scope så den kan bruges andre steder. Lad den aldrig forlade scope med objekter, og sæt referencen til null når du er færdig så garbage collectoren bliver hjulpet. Evt. med et System.gc() kald.
Der er en dynamisk klasse kaldet StringBuffer du med fordel kan bruge. StringBuffer.toString().getBytes() giver dig dit array tilbage og StringBuffer.append((char[]) byte[]) evt. StringBuffer.append(new String(bytes[]) tilføjer dine arrays efterhånden. Husk at en String ER et byte array, dvs "\t\t" = {'\t','\t'} = {13,13}.
Avatar billede =maddog= Nybegynder
05. februar 2003 - 17:11 #14
Med dynamisk mener jeg mutable, altså uden de genstridigheder der er med arrays. I modsætning til en String bliver der ikke oprettet nye objekter når der føjes til StringBufferen.
Avatar billede soelvpil Nybegynder
05. februar 2003 - 20:12 #15
Du har fået et godt svar, men desværre ikke det du håbede på.

Efter min mening ville en nogenlunde rimelig løsning være at give arne_v nogle af pointene, og selv beholde resten...
Avatar billede =maddog= Nybegynder
06. februar 2003 - 01:27 #16
Jeg er enig med soelvpil. Problemet kan ikke løses på nogen let måde. Problemet er jo basalt set at:
1) Man kan ikke lave en instans af et array uden en kendt længde.
2) Man kan ikke vide hvilken lændge arrayet skulle have haft før det ikke længere er i anvendelse.
Med ordet Stream ligger det jo også implicit, at der kommer en strøm af bytes en efter en indtil kilden er udtømt. Der er ikke nogen som helst mulighed for at aflæse hvor mange bytes der kommer (med mindre der er tale om et specielt format med en header som sendes først).
Så efter min mening har du to muligheder:
1) Anvende arne_v's løsning med en tilpas buffer (bedst), eller
2) Anvende min løsning, der udelukkende udspringer af dine krav, med en buffer der kan rehashes til et større indhold.
Jeg har en klasse til at læse multipart http request og lave en nøjagtig kopi af vedhæftede filer en efter en hvis det har interesse, men denne anvender arne_v's løsningsmodel der i alle henseender er optimal (strømmer BLIVER afbrudt undervejs, tro mig. Du kan ikke forvente at få 30 kilobytes uden en eneste dårlig pakke).
Avatar billede anadan Nybegynder
07. februar 2003 - 12:25 #17
Jeg er villig til at give arne_v 20p og =maddog= 10p hvis i virkelig mangler de point.
Avatar billede =maddog= Nybegynder
07. februar 2003 - 13:16 #18
nu kan jeg ikke købe leverpostej for de point, så jeg er egentlig ligeglad hvis du virkelig gerne vil beholde dem.
Avatar billede anadan Nybegynder
07. februar 2003 - 13:19 #19
jeg er ligeglad med point, men den tidligere diskussion lægger bare op til at nogen virkelig mangler de point, det var ikke specielt rettet mod dig. Hvis der er nogen der mangler dem mere end mig er de da velkomne...
Avatar billede =maddog= Nybegynder
07. februar 2003 - 13:21 #20
jamen jeg mangler ikke points. for mig er den venlige tanke pointene afspejler mere end nok :-).
Avatar billede arne_v Ekspert
07. februar 2003 - 17:32 #21
Jeg synes, at du skal beholde dine point.

Men du skal nok heller ikke være overrasket, hvis der er nogen som
fremover ikke gider bruge tid på at svare på dine spørgsmål.

Du stiller et spørgsmål til X point, du får et korrekt svar, så stiller
du et tillægs spørgsmål, det får du også et korrekt svar på nemlig
at det ikke kan lade sig gøre, men fordi du ikke har fået løst dit
problem vil du først ikke give point og efter lidt debat vil du give <X
point.

Du bestemmer suverænt selv over dine point.

Men jeg (og alle andre) bestemmer også selv om, hvilke spørgsmål
vi vil bruge tid på. Og som maddog siger så kan man ikke købe
smør på brøddet for point. Og det er da for dumt at bruge sin tid
på at hjælpe nogen som ikke værdsætter det.
Avatar billede kasseper Nybegynder
19. februar 2003 - 12:01 #22
sig mig lige en gang, hvilken protokol er det du anvender ?
De fleste indehólder altså i deres header information hvor mange 'pakker' der er i hele beskeden, og du kan på den baggrund lave en beregning der siger dig hvor mange og hvor store buffere du skal lave...!
Avatar billede anadan Nybegynder
20. februar 2003 - 13:53 #23
Jeg bruger TCP, men jeg tror ikke jeg forstår hvad du mener. Hvilke metoder foreslår du da? Jeg ved at jeg kan bruge en ObjectStream men det vil jeg helst undgå...
Avatar billede anadan Nybegynder
20. februar 2003 - 13:58 #24
arne_v: jeg mener selv at jeg har givet udtryk for at jeg værdsætter dine løsninger. Jeg har da også brugt en del af dine forslag som udgangspunkt i min løsning, og er derfor villig til at give dig de point. På den anden side mener jeg at du giver udtryk for at du gerne vil have de point, og så kan du da bare indrømme det, så ville du da få de point. At have en lang diskussion over noget så tåbeligt er da for langt ude.
Avatar billede anadan Nybegynder
20. juli 2004 - 12:25 #25
ingen svar, lukker
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