2010-10-22 24 views
3

我最初使用RIM的本机xml解析器方法来解析一个150k的文本文件,大约有5000行xml,但它需要大约2分钟才能完成,所以我尝试了一种基于行的格式:在BlackBerry上解析文本文件需要永久

标题:书名
线1
线线3

我应该能够读取该文件在较短的时间比需要眨眼,但它仍然是缓慢的。

标识符书籍是书籍对象的向量,行存储在书籍对象中的字符串矢量中。

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(); 
} 
+0

为什么你不用传统的功能呢?例如没有任何LineReader。手动处理一个字符读取循环.. – 2010-10-22 05:42:45

回答

2

很容易假设您从代码示例中删除的所有操作都是在恒定时间内完成的。我猜测他们中的一个正在做低效率的事情,比如book.addLine(strLine);或者可能是_observer.processStatusUpdate(totalComplete , book.getTitle());如果这些操作无法在常量时间内完成,那么您可以很容易地使用二次分析算法。

想想这些操作是找出问题的最好方法,但是如果您难以理解,请尝试使用BlackBerry Profiler。在Eclipse调试器中运行程序,并在解析之前停止在断点处。然后,在Eclipse中,选择'window .. show view .. other .. BlackBerry .. BlackBerry Profiler View' 从分析器视图工具栏中选择'setup options'按钮。它在图标中有一个蓝色三角形。将“方法归因”设置为累积,将“要分析的内容”设置为“包括本地方法的时间”

然后继续您的程序。一旦解析完成,您需要暂停程序执行,然后单击探查器视图的“方法”选项卡。你应该能够从那里确定你的痛点。

+0

该错误与处理状态更新和我的猜测是在等待synchorize。谢谢你的帮助! – SS44 2010-10-22 18:57:20

0

尝试使用new BufferedInputStream(classs.getResourceAsStream(fileName));

编辑:

显然,documentation会说她们的BufferedInputStream是wrong

我要在这里留下这个错误的答案,所以人们有这样的信息(文件被错误)。

+0

BufferedInputStream似乎没有在我当前的5.0 api包中可用。 Eclipse在编译时似乎无法解决它。我试过使用ByteInputStream,但没有更好的最终结果。 – SS44 2010-10-22 06:19:08

+0

你有BufferedReader吗? – nos 2010-10-22 07:01:13

+1

这是J2ME - 没有这样的类 – 2010-10-22 07:06:13

0

探查器在哪里说你花费时间?

如果您没有首选的分析器,那么Java 6 JDK中有jvisualvm。

(我的猜测是,你会发现花费所有的时间在路上下调至“从文件读取字符”。如果是这样,你需要缓冲)

4

一件事,你在文件中读两次 - 一次用于确定大小,然后再解析它。由于您已经将它读入字节数组中以确定大小,为何不将该字节数组传递给ByteArrayInputStream构造函数?例如:

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

这样,如果类从流中读取的其余每次读一个字节都不会有问题 - 这一切都在内存中。

+0

感谢您的帮助,始终欢迎更清晰的代码/代码提示。 – SS44 2010-10-22 18:57:55