OpenOffice sehr langsam beim Laden einer Datei

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

OpenOffice sehr langsam beim Laden einer Datei

Beitrag 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?
luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

XInputStreamWrapper

Beitrag 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)
{
}
}
}
luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

Beitrag von luial »

Gibt es hier auch andere, die OO mittels Java-Streams nutzen?
hol.sten
******
Beiträge: 871
Registriert: Fr, 18.11.2005 21:21

Beitrag 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
luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

Beitrag von luial »

@hol.sten

Ja, bei XOutputStream klappt es auch bei mir wunderbar.
Aber wie liest du dann Dokumente ein?
hol.sten
******
Beiträge: 871
Registriert: Fr, 18.11.2005 21:21

Beitrag 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
luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

Beitrag 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.
luial
Beiträge: 6
Registriert: Di, 20.03.2007 12:50

Beitrag 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);

}
hol.sten
******
Beiträge: 871
Registriert: Fr, 18.11.2005 21:21

Beitrag 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
Antworten