ERLEDIGT
JA
JA
ANTWORTEN
15
15
ZUGRIFFE
4423
4423
EMPFEHLEN
-
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:PHP-Code: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();
}
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.PHP-Code: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;
}
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.Manuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
08.02.06 13:45 #2
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Wie man eine Datei zu einem Client streamen kann findest du hier:
http://www.tutorials.de/forum/java/2...light=Download
Die SVNConnector Klasse scheint eine Eigenenentwicklung von dir zu sein, bzw. kann ich diese nicht im javah SVN Verzeichnis finden:
http://svn.collab.net/viewcvs/svn/tr...ersion/javahl/
Schaut man sich das SVNClientInterface - Interface an: http://svn.collab.net/viewcvs/svn/tr...60&view=markup
So findet man die von dir genannte Methode:
In deinem geposteten Codeschnippsel kann ich den Aufruf dieser Methode leider nicht entdecken. (Hast du die vielleicht am SVNConnector implementiert?) Vielleicht solltest du diese Methode einfach mal direkt verwenden via SVNClient.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Write the file's content to the specified output stream. If * you need an InputStream, use a * PipedInputStream/PipedOutputStream combination. * * @param path the path of the file * @param revision the revision to retrieve * @param pegRevision the revision at which to interpret the path * @param the stream to write the file's content to * @throws ClientException * @see <a href="[URL="http://java.sun.com/j2se/1.4.2/docs/api/java/io/PipedOutputStream.html"]http://java.sun.com/j2se/1.4.2/docs/api/java/io/PipedOutputStream.html[/URL]">PipedOutputStream</a> * @see <a href="[URL="http://java.sun.com/j2se/1.4.2/docs/api/java/io/PipedInputStream.html"]http://java.sun.com/j2se/1.4.2/docs/api/java/io/PipedInputStream.html[/URL]">PipedInputStream</a> */ void streamFileContent(String path, Revision revision, Revision pegRevision, int bufferSize, OutputStream stream) throws ClientException;
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi,
die Methode "streamFileContent" rufe ich über meine "getFileContent" auf:
--> client = SVNClient();PHP-Code:public byte[] getFileContent(String path, Revision rev){
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
client.streamFileContent(path, rev, rev, 256, out);
} catch (ClientException e) {
jlog.error("Can't get file content from subversion.");
e.printStackTrace();
}
// TODO: The content should NOT be saved in a variable.
// TODO: The return type should be void or a stream.
// TODO: Big files would cause an java heap space exception.
byte[] content = out.toByteArray();
return content;
}
So läuft es im Moment. ( nur mit kleinen Files )
Hatte es auch schon mit PipedOutput/Input -Streams, allerdings helfen diese auch nichts, weil die Methode "streamFileContent" den overflow verursacht. Auch Threads scheinen in diesem Fall nichts zu bringen da ich nicht in den Prozess der native File eingreifen kann. Alles schon versucht
Gruß
- ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
08.02.06 14:09 #4
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Gibts vom eurem Projekt schon ne Lauffaehige Version? Wenn ja wuerde ich heute Abend mal mein Glueck versuchen.
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi,
kann dir das Projekt leider nicht schicken - siehe PM.
Für das Problem hier dennoch weiter, evtl. weis jemand anders bescheid oder man kann jemanden helfen.
In deinem Tutorial hast du alles ja schön beschrieben, das Problem ist nur dass ich durch Subversion keine reale Datei habe sondern nur einen vollen Stream und somit keinen File Stream erstellen kann. Bin gerade noch dabei ViewCVS Source zu durchstöbern um zu sehen wie diese das Problem gelöst haben.
Gruß
- ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
08.02.06 14:49 #6
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Hast du es schonmal mit:
versucht?Code :1 2 3 4 5
ServletOutputStream out = response.getOutputStream(); ... streamFileContent(strRepos + path,Revision.getInstance(revision), XXXX, 16384, out); ...
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi!
Jopp, schon versucht und auch schon mit dem response.getWriter().
Zudem tritt der overflow innerhalb der Methode streamFileContent auf, was bedeutet ich komm nicht weiter um den Stream in irgend einer Art zu Weise zu behandeln.
Vermute ich brauche einfach eine andere Methode, aber ich schau mich noch um.
Gruß
- ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
08.02.06 22:04 #8
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Folgendes:
...funktioniert mit einer (künstlich etwas aufgeblähten) 15 MB großen Nordwind.mdb einwandfrei. Ich denke so solltest du auch von einem Servlet aus Streamen können.Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
package de.tutorials; import java.io.File; import java.io.FileOutputStream; import org.tigris.subversion.javahl.Revision; import org.tigris.subversion.javahl.SVNClient; import org.tigris.subversion.javahl.SVNClientInterface; public class SVNRepositoryDownloadExample { /** * @param args */ public static void main(String[] args) throws Exception{ SVNClientInterface svnClient = new SVNClient(); svnClient.username("tom"); svnClient.password("tom"); FileOutputStream fileOutputStream = new FileOutputStream(new File("c:/Nordwind.mdb")); svnClient.streamFileContent("svn://localhost/de.tutorials.svn/Nordwind.mdb",Revision.getInstance(7L),Revision.getInstance(7L),16384,fileOutputStream); fileOutputStream.close(); } }
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi,
leider muss ich dir sagen das diese Möglichkeit auch nicht funktioniert.
Das Problem liegt einfach an der native Methode in die nicht eingegriffen werden kann.
Werd noch ein paar andere Möglichkeiten versuchen und bescheid geben wenn ich eine Lösung gefunden habe.
Gruß ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
09.02.06 09:59 #10
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Ich wette das funktioniert genau so wie oben beschrieben... ob ich nun die Datei in ein File streame oder ueber ein Servlet zum Client schicke ist doch egal
Ich baue heute Abend mal ein Beispiel dazu.
Ich habe uebrigens die entsprechenden Jars aus dem Subclipse Eclipse-Plugin verwendet.
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi Tom,
wir haben uns nun eine andere Lösung einfallen lassen.
Der Download wird über den Commandline Befehl "svn cat" durchgeführt und somit kann der STDOUT leicht gebuffert werden und an den User weitergeleitet werden. Für Uploads -muss- eine Working Copy vorhanden sein, welche wir somit auch führen werden (temporär).
Gute Nacht
- ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
10.02.06 10:03 #12
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Leider konnte ich mich gestern Abend nicht mehr an den rechner setzen...
Ich denke immernoch, dass das auch anders moeglich ist. Werde mich am WE mal damit beschaeftigen.
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
10.02.06 13:50 #13
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
package de.tutorials.web.svn.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.tigris.subversion.javahl.ClientException; import org.tigris.subversion.javahl.Revision; import org.tigris.subversion.javahl.SVNClient; import org.tigris.subversion.javahl.SVNClientInterface; /** * Servlet implementation class for Servlet: SVNDownloadServlet * * @web.servlet name="SVNDownloadServlet" display-name="SVNDownloadServlet" * * @web.servlet-mapping url-pattern="/SVNDownloadServlet" * */ public class SVNDownloadServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { /* * (non-Java-doc) * * @see javax.servlet.http.HttpServlet#HttpServlet() */ public SVNDownloadServlet() { super(); } /* * (non-Java-doc) * * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, * HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=eclipse.dat;"); SVNClientInterface svnClient = null; try { svnClient = new SVNClient(); svnClient.username("tom"); svnClient.password("tom"); svnClient.streamFileContent( "svn://localhost/de.tutorials.web.svn/eclipse.zip", Revision.getInstance(14L), Revision.getInstance(14L), 16384, response.getOutputStream()); } catch (ClientException e) { e.printStackTrace(); } finally { if (svnClient != null) { svnClient.dispose(); } } } }
Funktioniert bei mir ohne Probleme
Im Browser kommt ein "Datei speichern unter" Dialog hoch.
Ich denke das ist etwas bequemer als den OUTPUT auf der Konsole zu verarbeiten...
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
Hi Tom,
bin schon zuhause, aber ich weis das haben wir schon versucht und mit großen Files entstehen dadurch Probleme. Nicht das mich mcih evtl die ganze Zeit falsch verstanden hast, aber mit normalen kleinen txt Files hab ich schon dutzende Varianten zum laufen gebracht. Das Problem ist wenn ich Dateien mit 300 MB oder mehr herunterladen will. Versuch es mal bei dir, wirst sehen das du einen "Java heap space" bekommst.
Gruß
- ManuelManuel Freiholz
iF.Gainwar
iF.SVNAdmin (http://www.insanefactory.com/if-svnadmin/)
Subversion Benutzeradministration mit PASSWD und LDAP Integration.
-
10.02.06 14:00 #15
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo!
1) Okay das habe ich noch nicht evrsucht... meine groessten Dateien waren 30 MB.
2) Was haben so grosse binaere Dateien in einem Repository zu suchen?! Das ist in meinen Augen Bloedsinn... die sollte man woanders (ausserhalb des Repositories) ablegen.
Edit:
Das Problem scheint ein Memory leak in einer der javahl DLLs zu sein. Bei mir bleibt der Speicherverbrauch im taskmanager bei 17-18 MB (Tomcat Prozess). Schaue ich hingegen unter dem reiter Performance auf den Status der Auslagerungsdatei, so waechst diese alle 30 Sekunden um 15 MB... habs mal mit einem 300 MB grossen Zip File ausprobiert. Scheinbar wird dort der byte[] Puffer nicht mehr freigegeben...
Im javasvn.jar im subclipse Plugin findet man noch SVNWCClient dieser bietet auch eine Methode doGetFileContents(....) an welche keine Probleme mit grossen Dateien hat. Allerdings wird dazu auf dem Server eine temporaere Datei erstellt welche dann zum Client gestreamt und danach geloescht wird.
Gruss TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
Ähnliche Themen
-
Subversion Hosting
Von eagle1985 im Forum Hosting & WebserverAntworten: 6Letzter Beitrag: 21.01.11, 22:06 -
Subversion Konfiguration
Von caramba12321 im Forum Linux & UnixAntworten: 1Letzter Beitrag: 05.11.09, 00:18 -
Subversion
Von Arndtinho im Forum Coders TalkAntworten: 2Letzter Beitrag: 03.05.07, 08:51 -
Subversion Server
Von ava99 im Forum Hosting & WebserverAntworten: 4Letzter Beitrag: 03.01.07, 00:48





Zitieren

Login





