Java: Lesen einer pdf-Datei von URL in eine Byte-array/ByteBuffer in ein applet
Ich versuche, herauszufinden, warum dieser bestimmte code-snippet nicht für mich arbeiten. Ich habe ein applet soll zu Lesen .pdf und Anzeige mit einem pdf-renderer-Bibliothek, aber aus irgendeinem Grund, wenn ich in der lese .pdf-Dateien, die sitzen auf meinem server, Sie am Ende als korrupt. Ich habe es getestet, indem Sie die Dateien wieder raus.
Ich habe versucht, das betrachten der Applets im IE und Firefox und die beschädigten Dateien auftreten. Komisch ist, wenn ich versuche die Anzeige des Applets in Safari (für Windows), die Datei ist eigentlich in Ordnung! Ich verstehe die JVM vielleicht anders, aber ich bin immer noch verloren. Ich habe kompiliert in Java 1.5. JVMs sind 1.6. Das snippet liest die Datei ist unten.
public static ByteBuffer getAsByteArray(URL url) throws IOException {
ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
URLConnection connection = url.openConnection();
int contentLength = connection.getContentLength();
InputStream in = url.openStream();
byte[] buf = new byte[512];
int len;
while (true) {
len = in.read(buf);
if (len == -1) {
break;
}
tmpOut.write(buf, 0, len);
}
tmpOut.close();
ByteBuffer bb = ByteBuffer.wrap(tmpOut.toByteArray(), 0,
tmpOut.size());
//Lines below used to test if file is corrupt
//FileOutputStream fos = new FileOutputStream("C:\\abc.pdf");
//fos.write(tmpOut.toByteArray());
return bb;
}
Ich muss etwas fehlen, und ich habe schlug meinen Kopf zu versuchen, es herauszufinden. Jede Hilfe wird sehr geschätzt. Danke.
Edit:
Zur weiteren Klärung meiner situation, die Differenz, bevor Sie die Datei lese ich dann mit dem snippet und nach, ist, dass diejenigen, denen ich die Ausgabe nach der Lektüre sind deutlich kleiner, als Sie ursprünglich sind. Wenn Sie diese öffnen, werden Sie nicht anerkannt .pdf Dateien. Es gibt auch keine exceptions geworfen, die ich Ignoriere, und ich habe versucht, eine Spülung ohne Erfolg.
Dieses snippet funktioniert in Safari, das heißt, die Dateien werden gelesen in seiner Gesamtheit, mit keinen Unterschied in der Größe, und kann geöffnet werden mit jedem .pdf-reader. Im IE und Firefox werden die Dateien immer am Ende wird beschädigt, konsequent die gleiche geringere Größe.
Ich überwacht die len-variable (beim Lesen einer Datei 59kb), in der Hoffnung, um zu sehen, wie viele bytes zu Lesen bekommen in jeder Schleife. Im IE und Firefox, bei 18kb, die in.read(buf) liefert eine -1, wenn die Datei beendet ist. Safari tut dies nicht.
Werde ich halten, und ich Schätze all die Vorschläge so weit.
- Wenn Sie sagen, dass die Datei beschädigt ist, was meinst du genau? Wenn du im Vergleich zu den ursprünglichen, was ist anders?
- Beantworten Sie bitte den 2. Teil von Eddie ' s Frage. Auch ist der Wert von contentLength richtig?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur im Fall, dass diese kleinen änderungen einen Unterschied machen, versuchen Sie dies:
Du hast vergessen zu schließen
fos
was dazu führen kann, dass die Datei wird kürzer, wenn Ihre Anwendung noch läuft oder ist abrupt beendet. Ebenfalls neu ist die Schaffung derByteArrayOutputStream
mit der entsprechenden Ausgangsgröße. (Sonst Java wird wiederholt Zuweisung ein neues array und kopieren, weisen Sie eine neue array kopieren, das wird teuer.) Ersetzen Sie den Wert 16384 mit einem besser passenden Wert. 16k ist wahrscheinlich zu klein für eine PDF, aber ich weiß nicht wie, aber die "Durchschnittliche" Größe ist, dass Sie erwarten, um zu laden.Da Sie Verwendung
toByteArray()
zweimal (auch wenn man im Diagnose-code), habe ich zugewiesen, dass auf eine variable. Schließlich, obwohl es nicht sollte keinen Unterschied machen, wenn Sie das einwickeln der gesamte array in einen ByteBuffer, Sie brauchen nur zu liefern, das byte-array selbst. Liefert den offset0
und die Länge ist überflüssig.Beachten Sie, dass wenn Sie das herunterladen großen PDF-Dateien auf diese Weise, dann stellen Sie sicher, dass Sie in der JVM ausgeführt wird, mit einem ausreichend großen Haufen, dass Sie genug Platz für mehrere Male, die größte Dateigröße, die Sie erwarten, zu Lesen. Die Methode, die Sie verwenden hält die ganze Datei in den Arbeitsspeicher, das ist OK, solange Sie es sich leisten können, dass der Speicher. 🙂
Ich dachte, ich hatte das gleiche problem wie du, aber es stellte sich heraus, mein problem war, dass ich davon ausgegangen, dass Sie immer die Puffer voll, bis Sie nichts bekommen. Aber man nicht davon ausgehen, dass.
Die Beispiele auf dem Netz (z.B. java2s/tutorial) verwenden Sie einen BufferedInputStream. Aber das macht keinen Unterschied für mich.
Könnten Sie prüfen, ob Sie tatsächlich die vollständige Datei in der Schleife. Als wäre das problem in den ByteArrayOutputStream.
Haben Sie versucht, eine
flush()
bevor Sie in der Nähe dertmpOut
stream um sicherzustellen, dass alle bytes geschrieben?