2012-11-29 15 views
5

Ich arbeite an etwas Java-Code, der schließlich innerhalb eines App-Servers verwendet werden wird, um auf einige wirklich große Dateien (über 1 GB, unter 20 GB) zuzugreifen, möglicherweise gehostet auf einem NFS Aktie. eine individuelle Anfrage Wartung wird beinhaltet dies zu tun:java.io.RandomAccessFile Skalierbarkeit (oder andere Optionen)

  1. Finden Sie die große Datei I
  2. Navigieren Sie zu einem beliebigen Punkt in der Datei
  3. Lese aus dieser Datei Bytes (in der Regel unter 1 MB)
  4. lesen muß
  5. Rück diesen Bytes

ich habe einigen glücklichen einfachen POC-Code in dem Moment, einfach eine neue Datei schreibgeschützt öffnet und das schließt es:

RandomAccessFile raf=new RandomAccessFile(myFileName, "r"); 
try{ 
    byte[] buffer = new byte[size]; 
    raf.seek(position); 
    raf.reafFully(buffer); 
    return buffer; 
} 
finally{ 
    raf.close(); 
} 

Ich frage mich, ob dies ein elegant einfacher Ansatz ist, der wirklich gut funktionieren sollte, oder ein dummer vereinfachender Ansatz, der unter hoher Last viele Probleme haben wird (und vielleicht muss ich einen thread-sicheren Pool von Leser usw.). Natürlich wäre es am besten, diese Annahme zu testen, aber ich habe mich gefragt, ob es Best Practices oder bekannte Probleme bei beiden Ansätzen gibt. Bis jetzt war ich nicht in der Lage, sehr viel googlen herauszufinden ...

Danke!

PS. Es ist noch nicht klar, ob die endgültige Version auf Windows oder * nix gehostet werden würde. Es ist auch nicht klar, wie die großen Dateien geteilt werden. PPS. Die App-Server werden wahrscheinlich in einem Cluster konfiguriert, sodass zwei verschiedene App-Server möglicherweise dieselbe große freigegebene Datei zur gleichen Zeit lesen müssen.

+1

sieht gut aus für mich. Sie können nicht schneller als das, es sei denn, Sie die Datei auf dem lokalen Datenträger oder im Speicher zwischenspeichern – irreputable

+0

So sind die Kosten für das Öffnen und Freigeben von Dateigriffen vernachlässigbar? Sogar über, sagen wir, eine NFS-Freigabe? – Dave

+0

das ist wahrscheinlich nicht vernachlässigbar, sogar auf lokalen Dateien. Wenn es sich um ein Problem handelt, können Sie einen Pool von Handles behalten. oder, halte 1 'FileChannel' offen, lies es gleichzeitig durch' read (dst, position) ' – irreputable

Antwort

2

Eine andere Option ist Java NIO, nämlich FileChannel. FileChannel ist auch navigierbar und es kann schneller als RandomAccessFile sein, da es mit so genannten direkten Puffer arbeiten kann. Es hat einige interessante Features, zB ist es unterbrechbar.

+0

Guten Ruf. Ja, ich habe mit denen getestet. Es scheint, dass es vernachlässigbar schneller, aber nicht schneller genug ist, um die Komplexität in diesem speziellen Anwendungsfall zu rechtfertigen. Ich wurde kürzlich von Nio wegen eines physischen Windows-Speicherlecks in der JVM auf einer anderen App gebrannt, so dass ich ein bisschen zögerlich war, es seitdem zu benutzen. Ehrlich gesagt, wenn der Random-Access-Ansatz sowohl unter Last als auch bei Single-Thread-Tests funktioniert, ist er perfekt für mich. – Dave

+0

Richtig, noch überprüfen Sie dies, wenn http://StackOverflow.com/Questions/1605332/Java-Nio-filechannel-versus-fileoutputstream-performance-ususefulness noch nicht haben –