2009-07-08 13 views
5

Utilizziamo questo piccolo metodo di utilità. Ma non ci piace. Dal momento che non è molto cruciale (funziona comunque ...), l'abbiamo dimenticato.
Ma questo è brutto, perché dobbiamo passare attraverso l'intero array, solo per convertire da Byte[] a byte[].
Sto cercando:List <Byte> to String, puoi aiutare a rifattorizzare questo (piccolo) metodo?

  • di un modo per lanciare la Byte[] in byte[] senza passare attraverso di essa
  • o per un metodo di utilità per la fusione di una lista in stringa

public static String byteListToString(List<Byte> l, Charset charset) { 
    if (l == null) { 
     return ""; 
    } 
    byte[] array = new byte[l.size()]; 
    int i = 0; 
    for (Byte current : l) { 
     array[i] = current; 
     i++; 
    } 
    return new String(array, charset); 
} 
+2

Primo pensiero ... ti riferisci a metodi come "lei"? – sisve

+0

perché no? Le donne sono quelle logiche –

+3

Asker è francese; Il metodo francese è "la methode" (il francese è una lingua con il genere); la traduzione naturale in inglese produce "lei". Penso che sia divertente :) Se le auto e le navi possono essere tradizionalmente femminili, perché non i metodi? – AakashM

risposta

8

Il tuo metodo è praticamente l'unico modo per farlo. Potresti trovare una libreria esterna che fa tutto o parte di essa, ma essenzialmente farà la stessa cosa.

Tuttavia, c'è una cosa nel codice che rappresenta un potenziale problema: quando si chiama new String(array), si utilizza la codifica predefinita della piattaforma per convertire i byte in caratteri. La codifica della piattaforma differisce tra il sistema operativo e le impostazioni locali: utilizzarlo è quasi sempre un bug che aspetta di accadere. Dipende da dove stai ricevendo quei byte, ma la loro codifica dovrebbe essere specificata da qualche parte, passata come argomento al metodo e utilizzata per la conversione (usando il costruttore String con un secondo parametro).

+0

+1 per indicare il problema di codifica – dfa

-2

Scopri il BitConverter classe, penso che faccia quello che vuoi. Usalo in combinazione con il metodo List.toArray().

+0

Perché il downvote? Fa esattamente quello che vuoi ??? – Colin

+1

Questa è una domanda java, non .net. –

+0

È piuttosto interessante, tuttavia, che il codice assomigli esattamente a C#. Se non fosse per il tag "Java", non ci sarebbe modo di dirlo. Forse abbiamo bisogno di un modo più chiaro per indicare il linguaggio nelle domande di programmazione in cui potrebbe esserci ambiguità. –

3
import org.apache.commons.lang.ArrayUtils; 

... 

Byte[] bytes = new Byte[l.size()]; 
l.toArray(bytes); 

byte[] b = ArrayUtils.toPrimitive(bytes); 
+1

Non penso che questo sia un miglioramento, si sta aggiungendo una dipendenza a una libreria di terze parti, che internamente probabilmente farà qualcosa di simile al codice sopra comunque. – Jon

+0

@Jon: Sono parzialmente d'accordo - non mi piace aggiungere dipendenze di terze parti solo per l'util bit. metodo ma se questa dipendenza esiste già allora penso che renda il codice più succinto e leggibile. – Adamski

+0

@Jon Sono anche parzialmente d'accordo, ma commons-lang è probabilmente una delle librerie di terze parti più sicure da usare, come Adamski dice che probabilmente ne avresti fatto uso più di una volta. –

1

senza alcuna libreria aggiuntiva (ad esempio Apache Commons) il metodo va bene

-1

Una possibilità potrebbe essere quella di utilizzare StringBuilder:

public static String byteListToString(List<Byte> l) { 
    if (l == null) { 
     return "" ; 
    } 
    StringBuilder sb = new StringBuilder(l.size()); 

    for (Byte current : l) { 
     sb.append((char)current); 
    } 

    return sb.toString(); 
} 

Oppure, se avete bisogno di conversione dei caratteri

public static String byteListToString(List<Byte> l) { 
    if (l == null) { 
     return "" ; 
    } 
    ByteArrayOutputStream bout = new ByteArrayOutputStream(l.size()); 

    for (Byte current : l) { 
     bout.write(current); 
    } 

    return bout.toString("UTF-8"); 
} 

Se si stanno aggregando byte, provare ByteArrayOutputStream in primo luogo anziché Elenco di byte S. Nota: fai attenzione a UnsupportedEncodingException: dovrai provare a recuperarlo da qualche parte.

+0

Entrambi i frammenti sono molto più lenti e la memoria inefficiente, rispetto a quella pubblicata da OP. –

1

nit minore:

if (l == null || l.isEmpty()) { 
    return "" ; 
} 

per evitare la creazione di stringhe vuote per gli elenchi vuoti.

0

Si potrebbe utilizzare java.nio e venire con qualcosa di simile

public static String byteListToString(List<Byte> l, Charset cs) 
throws IOException 
{ 
    final int CBUF_SIZE = 8; 
    final int BBUF_SIZE = 8; 

    CharBuffer cbuf = CharBuffer.allocate(CBUF_SIZE); 
    char[] chArr = cbuf.array(); 
    ByteBuffer bbuf = ByteBuffer.allocate(BBUF_SIZE); 
    CharsetDecoder dec = cs.newDecoder(); 
    StringWriter sw = new StringWriter((int)(l.size() * dec.averageCharsPerByte())); 

    Iterator<Byte> itInput = l.iterator(); 
    int bytesRemaining = l.size(); 
    boolean finished = false; 
    while (! finished) 
    { 
     // work out how much data we are likely to be able to read 
     final int bPos = bbuf.position(); 
     final int bLim = bbuf.limit(); 
     int bSize = bLim-bPos; 
     bSize = Math.min(bSize, bytesRemaining); 
     while ((--bSize >= 0) && itInput.hasNext()) 
     { 
      bbuf.put(itInput.next().byteValue()); 
      --bytesRemaining; 
     } 
     bbuf.flip(); 
     final int cStartPos = cbuf.position(); 
     CoderResult cr = dec.decode(bbuf, cbuf, (bytesRemaining <= 0)); 
     if (cr.isError()) cr.throwException(); 
     bbuf.compact(); 
     finished = (bytesRemaining <= 0) && (cr == CoderResult.UNDERFLOW); 
     final int cEndPos = cbuf.position(); 
     final int cSize = cEndPos - cStartPos; 
     sw.write(chArr, cStartPos, cSize); 
     cbuf.clear(); 
    } 
    return sw.toString(); 
} 

ma io davvero non credo che mi consiglia per qualcosa di così semplice.

1

Guava fornisce una serie di utili primitive utilities, tra cui una classe Bytes che rende queste e altre operazioni su collezioni di Byte s banale.

private static String toString(List<Byte> bytes) { 
    return new String(Bytes.toArray(bytes), StandardCharsets.UTF_8); 
} 
Problemi correlati