2009-12-17 7 views
7

So habe ich etwas Code, der eine bestimmte Anzahl von Bytes aus einer Datei liest und das resultierende Byte-Array zurückgibt (das wird im Grunde für chunking-Dateien verwendet, um über das Netzwerk als (eventuell) base64-codierten ascii Text zu senden).Java: Wie "trim" ein Byte-Array?

Es funktioniert gut, außer, wenn der letzte Teil der Datei generiert wird, ist es nicht ein voller Chunk. Daher ist das resultierende Byte-Array nicht voll. Es ist jedoch eine konstante Größe, was bedeutet, dass die Datei wieder zusammengesetzt wird, es gibt eine ganze Reihe von zusätzlichen Daten (0 möglicherweise) an das Ende angehängt.

Wie kann ich es so machen, dass das Byte [] für den letzten Teil der Datei wirklich nur die Daten enthält, die es benötigt? Der Code sieht wie folgt aus:

private byte[] readData(File f, int startByte, int chunkSize) throws Exception { 
    RandomAccessFile raf = new RandomAccessFile(f, "r"); 
    raf.seek(startByte); 
    byte[] data = new byte[chunkSize]; 
    raf.read(data);   
    raf.close(); 
    return data; 
} 

Also, wenn chunkSize größer als die verbleibenden Bytes in der Datei ist, ein voller Größe byte [] wird zurückgegeben aber es ist nur halb voll mit Daten.

Antwort

3

Sie müssen den Rückgabewert von RandomAccessFile.read() überprüfen, um die Anzahl der gelesenen Bytes zu ermitteln. Wenn es sich von der chunkSize unterscheidet, müssen Sie das Array auf ein kleineres kopieren und das Array zurückgeben.

private byte[] readData(File f, int startByte, int chunkSize) throws Exception { 
    RandomAccessFile raf = new RandomAccessFile(f, "r"); 
    raf.seek(startByte); 
    byte[] data = new byte[chunkSize]; 
    int bytesRead = raf.read(data); 
    if (bytesRead != chunkSize) { 
     byte[] smallerData = new byte[bytesRead]; 
     System.arraycopy(data, 0, smallerData, 0, bytesRead); 
     data = smallerData; 
    } 
    raf.close(); 
    return data; 
} 
+1

Mit Arrays.copyOf von dem Pfosten anstelle des oben System.arraycopy (die warf eine Ausnahme), das hat perfekt funktioniert! Vielen Dank! –

+0

Korrigiert, ich hatte einen Tippfehler im Vergleich, hätte '== 'not' = 'verwenden sollen. – notnoop

+0

@Erin Drummond: Was war die Ausnahme von 'System.arraycopy()' geworfen? – Asaph

2

RandomAccessFile.read() gibt die Anzahl der gelesenen Bytes, so können Sie das Array tun kopieren, wenn erforderlich:

private byte[] readData(File f, int startByte, int chunkSize) throws Exception { 
    RandomAccessFile raf = new RandomAccessFile(f, "r"); 
    raf.seek(startByte); 
    byte[] data = new byte[chunkSize]; 
    int read = raf.read(data); 
    raf.close(); 
    if (read == data.length) return data; 
    else 
     return Arrays.copyOf(data, read); 
} 

Wenn Sie Java Pre-6 verwenden, dann müssen Sie Arrays.copyOf selbst implementieren:

byte[] r = new byte[read]; 
System.arraycopy(data, 0, r, 0, read); 
return r; 
0

Sie können auch die Größe der Datei verwenden, um die verbleibende Anzahl an Bytes zu berechnen.

private byte[] readData(File f, int startByte, int chunkSize) throws Exception { 
    RandomAccessFile raf = new RandomAccessFile(f, "r"); 
    raf.seek(startByte); 
    int size = (int) Math.min(chunkSize, raf.length()-startByte); 
    byte[] data = new byte[size]; 
    raf.read(data); 
    // TODO check the value returned by read (throw Exception or loop) 
    raf.close(); 
    return data; 
} 

Auf diese Weise können die Kopie keine zusätzliche Array erstellen und nicht brauchen. Wahrscheinlich keine große Wirkung.
Ein wichtiger Punkt IMO: Überprüfen Sie den Wert von read zurückgegeben, ich denke, es kann weniger als die restlichen Bytes sein. Die Javadoc- Zustände:

Die Anzahl der Bytes gelesen wird, höchstens gleich der Länge der b