2015-01-05 8 views
8

Sto provando a convertire un file dalla sdcard in Base64 ma sembra che il file sia troppo grande e ottengo un OutOfMemoryError.Convertire un file (<100Mo) in Base64 su Android

Ecco il mio codice:

InputStream inputStream = null;//You can get an inputStream using any IO API 
inputStream = new FileInputStream(file.getAbsolutePath()); 
byte[] bytes; 
byte[] buffer = new byte[8192]; 
int bytesRead; 
ByteArrayOutputStream output = new ByteArrayOutputStream(); 
try { 
    while ((bytesRead = inputStream.read(buffer)) != -1) { 
     output.write(buffer, 0, bytesRead); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
bytes = output.toByteArray(); 
attachedFile = Base64.encodeToString(bytes, Base64.DEFAULT); 

Esiste un modo per andare in giro alla OutOfMemoryError mentre il deposito della stringa attachedFile?

+0

Usa questo codice sarà utile https://stackoverflow.com/a/47572643/3505534 – R2R

risposta

8

Base64 la codifica richiede 3 byte di input e li converte in 4 byte. Quindi se hai un file da 100 Mb che finirà per essere 133 Mb nel Base64. Quando lo converti in una stringa Java (UTF-16), la dimensione verrà raddoppiata. Per non parlare del fatto che durante il processo di conversione a un certo punto manterrai più copie in memoria. Non importa come lo fai, difficilmente funzionerà.

Questo è un codice leggermente più ottimizzato che utilizza Base64OutputStream e richiede meno memoria del codice, ma non terrei il respiro. Il mio consiglio sarebbe quello di migliorare ulteriormente il codice saltando la conversione in stringa e utilizzando il flusso di file temporaneo come output anziché ByteArrayOutputStream.

InputStream inputStream = null;//You can get an inputStream using any IO API 
inputStream = new FileInputStream(file.getAbsolutePath()); 
byte[] buffer = new byte[8192]; 
int bytesRead; 
ByteArrayOutputStream output = new ByteArrayOutputStream(); 
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT); 
try { 
    while ((bytesRead = inputStream.read(buffer)) != -1) { 
     output64.write(buffer, 0, bytesRead); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
output64.close(); 

attachedFile = output.toString(); 
+1

Grazie per la tua risposta! Guarderò in multipart (con retrofit) e altro ... – Labe

+0

funziona bene, grazie –

0
// Converting File to Base64.encode String type using Method 
    public String getStringFile(File f) { 
     InputStream inputStream = null; 
     String encodedFile= "", lastVal; 
     try { 
      inputStream = new FileInputStream(f.getAbsolutePath()); 

     byte[] buffer = new byte[10240];//specify the size to allow 
     int bytesRead; 
     ByteArrayOutputStream output = new ByteArrayOutputStream(); 
     Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT); 

      while ((bytesRead = inputStream.read(buffer)) != -1) { 
       output64.write(buffer, 0, bytesRead); 
      } 


     output64.close(); 


     encodedFile = output.toString(); 

     } 
     catch (FileNotFoundException e1) { 
       e1.printStackTrace(); 
      } 
      catch (IOException e) { 
       e.printStackTrace(); 
      } 
     lastVal = encodedFile; 
     return lastVal; 
    } 
Problemi correlati