Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing a text file on BlackBerry takes forever

I was originally using RIM's native xml parser methods to parse a 150k text file, approximately 5000 lines of xml, however it was taking about 2 minutes to complete, so I tried a line based format:

Title: Book Title
Line 1
Line 2
Line 3

I should be able to read the file in less time than it takes to blink, but it is still slow.

Identifier books is a Vector of Book objects and lines are stored in a vector of strings in the Book object.

class classs = Class.forName("com.Gui.FileLoader");
InputStream is = classs.getResourceAsStream( fileName );

int totalFileSize = IOUtilities.streamToBytes( is ).length;
int totalRead = 0;

//Thought that maybe a shared input stream would be faster, in this case it't not.
SharedInputStream sis = SharedInputStream.getSharedInputStream( classs.getResourceAsStream( fileName ) );

LineReader lr = new LineReader( sis );
String strLine = new String( lr.readLine() );
totalRead += strLine.length();

Book book = null;

//Loop over the file until EOF is reached, catch EOF error move on with life after that.
while(1 == 1){

    //If Line = Title: then we've got a new book add the old book to our books vector.
    if (strLine.startsWith("Title:")){

        if (book != null){
            books.addElement( book );
        }

         book = new Book();

         book.setTitle( strLine.substring( strLine.indexOf(':') + 1).trim() );

         strLine = new String( lr.readLine() );
         totalRead += strLine.length();
         continue;
    }

    int totalComplete = (int) (  ( (double) totalRead / (double) totalFileSize ) * 100.00);
    _observer.processStatusUpdate( totalComplete , book.getTitle() );

    book.addLine( strLine );

    strLine = new String( lr.readLine(), "ascii" );
    totalRead += strLine.length();
}
like image 494
SS44 Avatar asked Dec 29 '25 11:12

SS44


1 Answers

For one thing, you're reading in the file twice - once for determining the size and then again for parsing it. Since you're already reading it into a byte array for determining the size, why not pass that byte array into a ByteArrayInputStream constructor? For example:

//Used to determine file size and then show in progress bar, app is threaded.
byte[] fileBytes = IOUtilities.streamToBytes( is );
int totalFileSize = fileBytes.length;
int totalRead = 0;

ByteArrayInputStream bais = new ByteArrayInputStream( fileBytes );
LineReader lr = new LineReader( bais);

This way it won't matter if the rest of the classes reading from the stream are reading a byte at a time - it's all in-memory.

like image 91
Marc Novakowski Avatar answered Jan 01 '26 03:01

Marc Novakowski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!