Gainwar
Erfahrenes Mitglied
Hi,
bin zur Zeit dran eine Weboberfläche für Subversion zu programmieren. (Wie ViewCVS). Ich arbeite hierzu mit der aktuellen "svn-javahl-1.3", welche die neue Methode streamFileContent(...) zur Verfügung stellt.
Nun, wenn ein User auf ein File klickt bekommt er zusätzlich die Möglichkeit sich diese Datei herunterzuladen. Diese File soll nicht erst auf dem Server zwischengespeichert werden, sondern direkt an den User geschickt werden. An sich ja kein Problem, funktioniert auch gut. Das Problem ensteht erst wenn die Datei eine etwas höhere Größe hat, z.B. 80 MB und größer. Ganz klar eigentlich, den schließlich speichere ich die Datei in einem byte[] welche ich dann über ein Servlet an den User schicke. Hier ein bisschen Code meines Download Servlets:
Eigentlich liegt der Fehler auf der Hand, die Zwischenspeicherung im byte[] verursacht den Heap overflow. Falsch, der Fehler passiert bereits in der von der svn-javahl gegebenen Methode "streamFileContent", welche mir meinen übergebenen OutputStream füllt. Habe mir auch den native Code angesehen. Das Problem ist die Methode füllt den Stream komplett, womit ich keine Chance habe eine Bufferung vorzunehmen. Hier der native Codeteil welcher den Stream füllt:
Nun wäre meine Frage, wie kann ich den Stream -direkt- an den User zum Download weiterleiten, ohne vorher eine Working copy der File auf dem Server anzulegen.
Vielen Dank, Gruß
- Manuel
PS: Entschuldigung das ich PHP-Code boxen genommen habe, aber da dies die einzigen sind welche ein Highlight benutzen, nahm ich diese damit ihr den Code besser lesen könnt.
bin zur Zeit dran eine Weboberfläche für Subversion zu programmieren. (Wie ViewCVS). Ich arbeite hierzu mit der aktuellen "svn-javahl-1.3", welche die neue Methode streamFileContent(...) zur Verfügung stellt.
Nun, wenn ein User auf ein File klickt bekommt er zusätzlich die Möglichkeit sich diese Datei herunterzuladen. Diese File soll nicht erst auf dem Server zwischengespeichert werden, sondern direkt an den User geschickt werden. An sich ja kein Problem, funktioniert auch gut. Das Problem ensteht erst wenn die Datei eine etwas höhere Größe hat, z.B. 80 MB und größer. Ganz klar eigentlich, den schließlich speichere ich die Datei in einem byte[] welche ich dann über ein Servlet an den User schicke. Hier ein bisschen Code meines Download Servlets:
PHP:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Get request and params.
//String filename = request.getPathInfo();
long revision = Long.parseLong(request.getParameter("revision"));
String path = request.getParameter("path");
String filename = request.getParameter("filename");
// Set content type. (force download)
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + filename + ";");
//response.setHeader("Content-Length","...");
// Get the output stream.
ServletOutputStream out = response.getOutputStream();
// Get current instance of FacesContext and Application.
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
// Get controller and connector.
ControllerBean controller = (ControllerBean)app.createValueBinding("#{Controller}").getValue(fc);
SVNConnector svn_connector = (SVNConnector)controller.getConnector();
// Subversion repository url.
String strRepos = svn_connector.getRepository();
// File content.
byte[] content = svn_connector.getFileContent( strRepos + path, Revision.getInstance(revision));
// Initialize download.
out.write( content );
out.flush();
out.close();
}
Eigentlich liegt der Fehler auf der Hand, die Zwischenspeicherung im byte[] verursacht den Heap overflow. Falsch, der Fehler passiert bereits in der von der svn-javahl gegebenen Methode "streamFileContent", welche mir meinen übergebenen OutputStream füllt. Habe mir auch den native Code angesehen. Das Problem ist die Methode füllt den Stream komplett, womit ich keine Chance habe eine Bufferung vorzunehmen. Hier der native Codeteil welcher den Stream füllt:
PHP:
while (contentSize > 0)
{
size_t readSize = bufSize > contentSize ? contentSize : bufSize;
Err = svn_stream_read(read_stream, (char *)bufData, &readSize);
if (Err != NULL)
{
env->ReleaseByteArrayElements(buffer, bufData, 0);
svn_stream_close(read_stream);
JNIUtil::handleSVNError(Err);
return;
}
env->ReleaseByteArrayElements(buffer, bufData, JNI_COMMIT);
env->CallVoidMethod(outputStream, writeMethod, buffer, 0, readSize);
if (JNIUtil::isJavaExceptionThrown())
{
env->ReleaseByteArrayElements(buffer, bufData, 0);
svn_stream_close(read_stream);
return;
}
contentSize -= readSize;
}
Nun wäre meine Frage, wie kann ich den Stream -direkt- an den User zum Download weiterleiten, ohne vorher eine Working copy der File auf dem Server anzulegen.
Vielen Dank, Gruß
- Manuel
PS: Entschuldigung das ich PHP-Code boxen genommen habe, aber da dies die einzigen sind welche ein Highlight benutzen, nahm ich diese damit ihr den Code besser lesen könnt.