从sdcard读取和解析ascii文件的最快方法

时间:2011-07-23 18:43:02

标签: android

我正在开发一个应用程序,允许用户选择一个ascii文本文件(通常来自sdcard),该文件包含在opengl中呈现形状所需的数据。文件格式看起来像这样(还有一些其他行包含不太相关的数据):

normal -1.000000e+000 -5.551115e-016 0.000000e+000
vertex 1.387779e-014 0.000000e+000 1.000000e+001
vertex 0.000000e+000 2.500000e+001 1.000000e+001
vertex 1.387779e-014 0.000000e+000 0.000000e+000

典型文件大约为5mb,包含大约120,000多行数据。我已经尝试了几种方法来读取和解析文件,我似乎无法读取文件并在不到90秒的时间内解析数据 - 这显然比我想要的慢。

我尝试了三种方法:

1)我逐行读取文件并使用字符串split方法和空格作为分隔符

2)然后我尝试使用streamtokenizer为文件中的每个单词/数字创建一个令牌(字符串)列表。然后我浏览了列表,用我需要的数据填充了arraylists(一个列表中顶点的数字和另一个列表中法线的数字)。再次,这工作但很慢。相关的代码块:

    File f = new File(Environment.getExternalStorageDirectory()+"/"+filename);
    int fLen = (int)f.length();
    Log.d("msg:", "File contains " + fLen + " Characters");

    try {
        FileReader file = new FileReader(f);
        buf = new BufferedReader(file);
        FileParser st = new FileParser(buf);

        while (st.nextToken() != st.TT_EOF) {
            if (st.ttype==st.TT_WORD){
            if (st.sval.equals("vertex"))
            {
              st.nextToken();
              vertices.add((Double.valueOf(st.sval).floatValue()));
              st.nextToken();
              vertices.add((Double.valueOf(st.sval).floatValue()));
              st.nextToken();
              vertices.add((Double.valueOf(st.sval).floatValue()));
              indices.add((short)(nodeCount-1));
            }
            }
        }

streamtokenizer初始化如下:

public class FileParser extends StreamTokenizer
{

  public FileParser(Reader r)
  {
    super(r);
    setup();
  }

  public void setup()
  {
    resetSyntax();
    eolIsSignificant(true);   
    lowerCaseMode(true);

    wordChars('!', '~');

    whitespaceChars(' ', ' ');
    whitespaceChars('\n', '\n');
    whitespaceChars('\r', '\r');
    whitespaceChars('\t', '\t');
  }// End setup
}

3)基于一篇文章,我读到了一个关于计算文本文件中的单词的文章,该文件表示与使用char缓冲区相比,streamtokenizers很慢,我尝试将文件读入一个大的char缓冲区(必要时以块为单位)。我看到了一些改善,但只有20%。相关代码:

        FileReader file = new FileReader(f);
        char pos = "+".charAt(0);
        char neg = "-".charAt(0);
        char dec = ".".charAt(0);
        float[] normalVector=new float[3];

        int bufSize=500000;
        int offset=0;

        char[] buffer=new char[bufSize];
        while ((len=file2.read(buffer,offset,bufSize-offset)) != -1) {
            index=0;
            while (index < len+offset) {
                while ((index < (len+offset)) && !Character.isLetterOrDigit(buffer[index]) && !(buffer[index]==pos) && !(buffer[index]==neg) && !(buffer[index]==dec)) {
                    index++;
                    if ((index>bufSize-20)&&(len+offset==bufSize)) {
                        offset=len+offset-index;
                        for(int i=0; i<offset; i++){
                               buffer[i]=buffer[index+i];
                        }
                        index=len+offset;
                    }
                }
                start = index;
                while ((index < (len+offset)) && ((Character.isLetterOrDigit(buffer[index]) || buffer[index]==pos || buffer[index]==neg) || buffer[index]==dec)) {
                    index++;
                }
                if (start < (len+offset)) {
                    text = String.copyValueOf(buffer, start, index-start);
                    if (text.equals("vertex")) {
                        xyz=1;
                    } else if (xyz>0) {
                          vertices.add((Double.valueOf(text).floatValue()));
                          xyz=xyz+1;
                          if (xyz==4){
                              nodeCount++;
                              indices.add((short)(nodeCount-1));
                              xyz=0;
                          }
                    }
                }       
            }
        }

我必须遇到某些瓶颈。有什么想法吗?

0 个答案:

没有答案