我正在开发一个应用程序,允许用户选择一个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;
}
}
}
}
}
我必须遇到某些瓶颈。有什么想法吗?