2011-01-08 11 views
6

Mam aplikację na Androida, do której próbuję wysłać zdjęcie do serwera. Zrobiłem to za pomocą kodowania Base64 i działało całkiem dobrze, ale zajęło to zbyt dużo pamięci (i czasu), aby zakodować obrazek przed wysłaniem go.Java/Android: odczytywanie/zapisywanie tablicy bajtów przez gniazdo

Próbuję rozebrać aplikację na Androida do miejsca, w którym po prostu wysyła ona tablicę bajtów i nie układa się z jakimkolwiek schematem kodowania, dzięki czemu zaoszczędzi tyle pamięci i cykli procesora, jak to tylko możliwe.

To co chciałbym kod Android wyglądać:

public String sendPicture(byte[] picture, String address) { 
    try { 
     Socket clientSocket = new Socket(address, 8000); 
     OutputStream out = clientSocket.getOutputStream(); 
     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
     out.write(picture); 
     return in.readLine(); 
    } 
    catch(IOException ioe) { 
     Log.v("test", ioe.getMessage()); 
    } 
    return " "; 
} 

Serwer jest napisany w Javie. Jak napisać kod serwera, aby poprawnie pobrać dokładnie tę samą tablicę bajtów? Moim celem jest zaoszczędzenie jak największej liczby cykli procesora na systemie Android.

Do tej pory wszystkie wypróbowane metody spowodowały uszkodzenie danych lub zgłoszony wyjątek.

Każda pomoc zostanie doceniona.

Odpowiedz

2

Na podstawie komentarza Roberta i Zakiego, oto zmodyfikowany kod, który powinien działać lepiej.

public byte[] getPicture(InputStream in) { 
    try { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    byte[] data = new byte[1024]; 
    int length = 0; 
    while ((length = in.read(data))!=-1) { 
     out.write(data,0,length); 
    } 
     return out.toByteArray(); 
    } catch(IOException ioe) { 
    //handle it 
    } 
    return null; 
} 
3

spróbować czegoś takiego:

public byte[] getPicture(InputStream in) { 
    try { 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     int data; 
     while ((data = in.read())>=0) { 
      out.write(data); 
     } 
     return out.toByteArray(); 
    } catch(IOException ioe) { 
     //handle it 
    } 
    return new byte[]{}; 
} 
+0

Działa, ale bajt czytania bajtu ze strumienia jest całkowicie nieefektywny i powolny. Lepiej jest przeczytać co najmniej 1024 bajty na raz. – Robert

+0

Myślę, że zwracanie wartości null zamiast nowego bajtu [] {} byłoby lepszym pomysłem. – Zaki

0

Jeśli chcesz dwukierunkową komunikację, serwer musi wiedzieć, kiedy jesteś gotowy - należy poprzedzić długość pola 4 bajtowego na swojej stronie nadawcy wskazując liczbę bajty, które nadejdą.

Po stronie serwera czytasz długość, a następnie słuchasz, dopóki wszystko nie nadejdzie. Następnie możesz odpowiedzieć na twój ciąg potwierdzający.

Jeśli wystarczy wysłać tylko zdjęcie, możesz po prostu wysłać dane, a następnie zamknąć połączenie. Strona serwera jest zaimplementowana, jak pokazano przez @thejh.

Powiązane problemy