Avatar billede delley Nybegynder
09. juli 2004 - 08:28 Der er 9 kommentarer og
1 løsning

Problemer med InputStream fra web (http)

Hej,

Jeg er igang med at lave en MP3 afspiller der er kodet som en applet. Problemet er når jeg prøver at indlæse en Mp3 fil, for at læse ID3 tags, så kan jeg ikke læse hele InputStream'en...
Afspillning af selve filen går fint!

Jeg har lavet en lille test code der beskriver mit problem. Hvis jeg henter filen via file:// er der ingen problemer, men hvis jeg henter filen via http:// så funker det ikke...

Jeg kan ikke bruge file:// til noget da programmet er kodet som en applet og applets har ikke rettigheder til at bruge file:// (security exception).

Mit gæt er at når man bruger http:// så bliver kun en lille del af filen indlæst i bufferet (se output) og resten bliver hentet "as needed". Er der nogen måde man kan tvinge InputStream til at hente det hele eller kan man gøre noget andet?

PS: Har prøvet at bruge en BufferedInputStream samme resultat...

Test code:

import java.io.*;
import java.net.*;

public class Mp3FileInfo{

  public static void main(String[] args){
  try{
    Mp3FileInfo mp3 = new Mp3FileInfo();
    ID3Tag tag = mp3.readTag("file://C:\\USERS\\Programmer\\Tomcat5.0\\webapps\\Mp3Juke\\files\\TheWayWeTalk.mp3");
    System.out.println(tag.getTitle());

    ID3Tag tag2 = mp3.readTag("http://localhost:8080/Mp3Juke/files/TheWayWeTalk.mp3");
    System.out.println(tag2.getTitle());
  }catch(IOException ioe){
    System.out.println(ioe.getMessage());
  }
}

  public ID3Tag readTag(String inputfile) throws IOException {
    URL mp3 = new URL(inputfile);
    ID3Tag tag = null;

    InputStream in = mp3.openStream();
    BufferedInputStream buffer = new BufferedInputStream(in);

    System.out.println("available: " + buffer.available());

    if(buffer.available() > 128) {
      buffer.skip(in.available()-128);
      byte[] tagBytes = new byte[128];
      buffer.read(tagBytes);
      tag = new ID3Tag (tagBytes);
      return tag;
    }
      return null;
  }

}

output:

available: 2187638
The Way We Talk
available: 2666
(tom linie)

På forhånd tak,

delley
Avatar billede arne_v Ekspert
09. juli 2004 - 08:39 #1
available() er ikke god til sockets.

For disk fil returnerer den filens størrelse minus det der er læst.

For socket returnerer den det der tilfældigvis er nået frem over nettet
for tidspunktet for kaldet minus det der er læst.

Derfor bør man ned sockets altid læse i en while løkke indtil man
har fået det man vil have.
Avatar billede delley Nybegynder
09. juli 2004 - 08:43 #2
ahhh tænkte nok at det var noget i den retning. Prøver lige en hurtig test...vender tilbage...
Avatar billede delley Nybegynder
09. juli 2004 - 10:39 #3
hmmm har lidt problemmer her...

Hvordan får jeg læst alle byte ind i et array når jeg ikke kender størrelsen af arrayet (array = størrelsen af inputStream)?

delley
Avatar billede arne_v Ekspert
09. juli 2004 - 10:49 #4
Det kan du heller ikke.

Du er nødt til at allokere en buffer af en given størrelse, fylde den, processe
den, fylde bufferen igen ...

Ellers skal du få serveren til at forælle dig størrelsen.
Avatar billede arne_v Ekspert
09. juli 2004 - 10:50 #5
Hvis du i.s.f. bare at bruge URL bruger en HttpURLConnection bør du
kunne få oplysningen fra HTTP headeren !
Avatar billede arne_v Ekspert
09. juli 2004 - 10:57 #6
URL url = new URL(url);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.connect();
        int status = con.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            InputStream is = con.getInputStream();
            int totlen = con.getContentLength();
            ...
            is.close();
        } else {
            ...
        }
        con.disconnect();
Avatar billede delley Nybegynder
09. juli 2004 - 10:58 #7
jeg kan få størrelsen fra HttpURLConnection.getContentLength();

Men jeg har stadigvæk problemmet med at appende byte array til byte array...

nogle forslag?

delley
Avatar billede arne_v Ekspert
09. juli 2004 - 11:09 #8
Er det ikke bare:

            byte[] b = new byte[totlen];
            int ix = 0;
            int n;
            while((n = is.read(b, ix, b.length - ix)) >= 0) {
              ix += n;
            }

for at få det ind i et array ?
Avatar billede delley Nybegynder
09. juli 2004 - 11:12 #9
ups jo *rødmer* det er jo en gammel kending....har vidst hovedet fyldt med for mange ting lige nu... tak :)
Avatar billede arne_v Ekspert
09. juli 2004 - 11:16 #10
så vil jeg ligge et svar
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