Seite 1 von 1
OpenOffice sehr langsam beim Laden einer Datei
Verfasst: Di, 20.03.2007 13:00
von luial
Hallo zusammen,
ich nutze OO zur Konvertierung beliebiger Dokumente in das PDF-Format.
Klappt auch soweit ganz gut.
Ich lade über eine XInputStream-Implementierung das Quelldokument.
Sie hat folgende Signatur:
public int readBytes(
byte[][] b,
int length) throws NotConnectedException, com.sun.star.io.IOException
OO ruft meine Implementierung auf.
Jedoch immer mit dem Wert length = 1.
D. h. die Datei wird Byte-weise einzeln eingelesen !!!
Bei einer 200 kb großen Datei wird folglich mehr als 200.000 mal
die Funktion readBytes aufgerufen.
Und das dauert...
Hat jemand eine Idee, warum OO die readBytes()-Methode einzeln / ungepuffert für jedes Byte aufruft?
Oder liegt die Ursache woanders?
XInputStreamWrapper
Verfasst: Di, 20.03.2007 14:12
von luial
Hier meine Klasse XInputStreamWrapper
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.sun.star.io.BufferSizeExceededException;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XSeekable;
import com.sun.star.lang.IllegalArgumentException;
public class XInputStreamWrapper implements XInputStream, XSeekable
{
private InputStream in;
private int pos;
private byte[] buffer;
/**
*
*/
public XInputStreamWrapper(InputStream in)
{
this.in = in;
bufferStream(in);
}
/*
* (non-Javadoc)
* @see com.sun.star.io.XInputStream#readBytes(byte[][], int)
*
* [26.01.2007] alice ArrayOutOfBoundException verhindert, weil OpenOffice über die tatsächliche Dateigröße hinaus lesen will ?!
* Dieses Problem trat bei sehr kleinen (TXT-) Dateien auf, z. B. kleiner als 1 kb
*/
public int readBytes(
byte[][] b,
int length) throws NotConnectedException, com.sun.star.io.IOException
{
// System.out.println("readByte:" + length + " bytes:" + b.length);
int count = 0;
if (length > 0)
{
count = buffer.length - pos;
b[0] = new byte[length];
// nur noch den Rest lesen
if (length > count && count > 0)
{
System.arraycopy(buffer, pos, b[0], 0, count);
pos = buffer.length;
return count;
}
else if (pos < buffer.length)
{
System.arraycopy(buffer, pos, b[0], 0, length);
pos += length;
return length;
}
else
{
return 0;
}
}
else
{
b[0]= new byte[0];
}
return 0;
}
/*
* (non-Javadoc)
*
* @see com.sun.star.io.XInputStream#readSomeBytes(byte[][], int)
*/
public int readSomeBytes(
byte[][] arg0,
int arg1)
throws NotConnectedException, BufferSizeExceededException,
com.sun.star.io.IOException
{
//TODO check this later
// System.out.println("readSomeByte:" + arg1);
return readBytes(arg0, arg1);
}
/*
* (non-Javadoc)
*
* @see com.sun.star.io.XInputStream#skipBytes(int)
*/
public void skipBytes(int arg0)
throws NotConnectedException, BufferSizeExceededException,
com.sun.star.io.IOException
{
// System.out.println("skip:" + arg0);
pos += arg0;
}
/*
* (non-Javadoc)
*
* @see com.sun.star.io.XInputStream#available()
*/
public int available()
throws NotConnectedException, com.sun.star.io.IOException
{
return buffer.length - pos;
}
/*
* (non-Javadoc)
*
* @see com.sun.star.io.XInputStream#closeInput()
*/
public void closeInput()
throws NotConnectedException, com.sun.star.io.IOException
{
//help the gc
buffer = null;
}
public long getLength() throws com.sun.star.io.IOException
{
// System.out.println("getlength:" + buffer.length);
return buffer.length;
}
public long getPosition() throws com.sun.star.io.IOException
{
// System.out.println("position");
return pos;
}
public void seek(long arg0)
throws IllegalArgumentException, com.sun.star.io.IOException
{
// System.out.println("seek:" + arg0);
pos = (int) arg0;
}
private void bufferStream(InputStream in)
{
try
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
int current = -1;
byte[] b = new byte[2048];
// [25.02.2007] alice read(b, 0, current) durch read(b) ersetzt, weil sonst -1 zurückkommt bei Dateien < 2048 Bytes
while ((current = in.read(b)) != -1)
{
out.write(b, 0, current);
}
in.close();
in = null;
buffer = out.toByteArray();
out = null;
pos = 0;
}
catch (java.io.IOException e)
{
}
}
}
Verfasst: Mi, 21.03.2007 10:57
von luial
Gibt es hier auch andere, die OO mittels Java-Streams nutzen?
Verfasst: Mi, 21.03.2007 18:57
von hol.sten
luial hat geschrieben:Gibt es hier auch andere, die OO mittels Java-Streams nutzen?
Stream ja, XInputStream nein. Ich benötige nur den XOutputStream, und bei dem habe ich dein Problem nicht.
Regards
hol.sten
Verfasst: Do, 22.03.2007 08:11
von luial
@hol.sten
Ja, bei XOutputStream klappt es auch bei mir wunderbar.
Aber wie liest du dann Dokumente ein?
Verfasst: Fr, 23.03.2007 12:59
von hol.sten
luial hat geschrieben:Aber wie liest du dann Dokumente ein?
Mit "loadComponentFromURL()". Ich wüsste nicht, warum ich da einen XInputStream nehmen sollte.
Regards
hol.sten
Verfasst: Fr, 23.03.2007 13:03
von luial
hol.sten hat geschrieben:luial hat geschrieben:Aber wie liest du dann Dokumente ein?
Mit "loadComponentFromURL()". Ich wüsste nicht, warum ich da einen XInputStream nehmen sollte.
Regards
hol.sten
Ich muss Dokumente aus der Datenbank laden.
Diese lese ich über einen InpuStream aus.
Und dieser Stream wird mittels XInputStreamWrapper gekapselt.
Verfasst: Fr, 23.03.2007 13:07
von luial
Im übrigen lade ich Dokumente so:
/**
* Lädt ein Dokument von einem Stream
*/
private XComponent loadDocument(InputStream stream) throws com.sun.star.uno.Exception
{
PasswordRequestMode[] nInteractionTypes = new PasswordRequestMode[1];
nInteractionTypes[0] = PasswordRequestMode.PASSWORD_REENTER;
Object oInteractionHandler = this.mxMultiComponentFactory.createInstanceWithContext("com.sun.star.task.InteractionHandler", this.mxComponentContext);
XInitialization xInitInteractionHandler = (XInitialization) UnoRuntime.queryInterface(XInitialization.class, oInteractionHandler);
xInitInteractionHandler.initialize(nInteractionTypes);
PropertyValue[] aOpenProperties = new PropertyValue[7];
aOpenProperties[0] = Utilities.createPropertyValue("Hidden", Boolean.TRUE);
aOpenProperties[1] = Utilities.createPropertyValue("AsTemplate", Boolean.FALSE);
aOpenProperties[2] = Utilities.createPropertyValue("MacroExecutionMode", new Short(com.sun.star.document.MacroExecMode.NEVER_EXECUTE));
aOpenProperties[3] = Utilities.createPropertyValue("UpdateDocMode", new Short(com.sun.star.document.UpdateDocMode.NO_UPDATE));
aOpenProperties[4] = Utilities.createPropertyValue("InteractionHandler", xInitInteractionHandler);
aOpenProperties[5] = Utilities.createPropertyValue("Silent", Boolean.TRUE);
aOpenProperties[6] = Utilities.createPropertyValue("InputStream", new XInputStreamWrapper(stream));
/*
aOpenProperties[6] = Utilities.createPropertyValue("FilterName", new String("Text (encoded)"));
aOpenProperties[7] = Utilities.createPropertyValue("FilterOptions", new String("IBM_437,CRLF,Arial,ENGLISH (US)") );
*/
return this.mxComponentLoader.loadComponentFromURL("private:stream", "_blank", 0, aOpenProperties);
}
Verfasst: Fr, 23.03.2007 13:09
von hol.sten
luial hat geschrieben:hol.sten hat geschrieben:luial hat geschrieben:Aber wie liest du dann Dokumente ein?
Mit "loadComponentFromURL()". Ich wüsste nicht, warum ich da einen XInputStream nehmen sollte.
Ich muss Dokumente aus der Datenbank laden.
Diese lese ich über einen InpuStream aus.
Und dieser Stream wird mittels XInputStreamWrapper gekapselt.
OK, das ist natürlich anders als bei mir. Ich lese die Dokumente aus dem Filesystem.
Regards
hol.sten