Java 以res/raw格式读取文本文件,速度非常慢。使用BufferedReader
文本文件的大小为560 KB,大约有24500行。每一行都被添加到一个列表中。也许我的手机又旧又慢?手机型号:三星GT-S5570,搭载安卓2.3.4。 阅读大约需要30秒或更长的时间,我很确定我在Reader类之外的算法不是问题所在。还有谁遇到过类似的问题,或者知道问题可能是什么Java 以res/raw格式读取文本文件,速度非常慢。使用BufferedReader,java,android,Java,Android,文本文件的大小为560 KB,大约有24500行。每一行都被添加到一个列表中。也许我的手机又旧又慢?手机型号:三星GT-S5570,搭载安卓2.3.4。 阅读大约需要30秒或更长的时间,我很确定我在Reader类之外的算法不是问题所在。还有谁遇到过类似的问题,或者知道问题可能是什么 public class Reader { public List<String> read(String file) { Context ctx
public class Reader {
public List<String> read(String file) {
Context ctx = ApplicationContextProvider.getContext();
List<String> entries = new ArrayList<String>();
//Get res/raw text-file id.
int resId = ctx.getResources().getIdentifier(file,"raw", ctx.getPackageName());
InputStream inputStream = ctx.getResources().openRawResource(resId);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream), 8192);
try {
String test;
while (true) {
test = reader.readLine();
if (test == null)
break;
entries.add(test);
}
inputStream.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return entries;
}
}
公共类读取器{
公共列表读取(字符串文件){
Context ctx=ApplicationContextProvider.getContext();
列表项=新的ArrayList();
//获取资源/原始文本文件id。
int resId=ctx.getResources().getIdentifier(文件“raw”,ctx.getPackageName());
InputStream InputStream=ctx.getResources().openRawResource(resId);
BufferedReader=new BufferedReader(new InputStreamReader(inputStream),8192);
试试{
串试验;
虽然(正确){
test=reader.readLine();
if(test==null)
打破
条目。添加(测试);
}
inputStream.close();
reader.close();
}捕获(IOE){
e、 printStackTrace();
}
返回条目;
}
}
如果使用apache“commons io”中的IOUtils,则更容易
InputStream is = getResources().openRawResource(R.raw.yourNewTextFile);
String s = IOUtils.toString(is);
IOUtils.closeQuietly(is); // don't forget to close your streams
你可以从
或
您描述的设备是一种非常旧且速度较慢的设备。您应注意通过以下方式尽可能加快阅读过程:
- 将ArrayList初始化为预期条目的大小,以便在添加条目时不会多次调整自身大小。当数组增长时,这需要多次执行大量操作,因为它必须在增长时再次复制所有以前的元素
- 一次读取整个文件,然后分析结果
private char[]readWholeFile(字符串文件){
Context ctx=ApplicationContextProvider.getContext();
int resId=ctx.getResources().getIdentifier(文件“raw”,ctx.getPackageName());
InputStream InputStream=ctx.getResources().openRawResource(resId);
BufferedReader=new BufferedReader(new InputStreamReader(inputStream),8192);
试一试{
int length=inputStream.available();
字符[]内容=新字符[长度];
reader.read(内容,0,长度);
返回内容;
}捕获(IOE异常){
e、 printStackTrace();
返回null;
}最后{
试一试{
if(reader!=null)reader.close();
}捕获(例外e){
}
}
}
公共列表读取条目(){
最终整数预期_元素=24500;
char[]contents=readWholeFile(“somefile”);
if(contents==null){
返回新的ArrayList();
}
列表条目=新的ArrayList(预期的_元素);
串试验;
BufferedReader reader=新BufferedReader(新字符读取器(内容));
试一试{
而((test=reader.readLine())!=null){
条目。添加(测试);
}
返回条目;
}捕获(IOE异常){
e、 printStackTrace();
返回新的ArrayList();
}最后{
试一试{
if(reader!=null)reader.close();
}捕获(例外e){
}
}
}
由于某些原因,如果我不将数组设置为固定大小24500,所需的时间会更少。无固定尺寸:35910484987纳秒。固定尺寸:36759156654纳秒。然后我尝试了你的方法:readWholeFile方法需要281223333纳秒,readEntries需要4585771666纳秒。因此,除了固定大小的数组(!?)之外,您的解决方案要快得多。它会在另一个类中导致数组索引外问题,但这是一个完全不同的谜团。:)谢谢您的帮助。实际上构造ArrayList(初始容量)并不会创建固定数组,而是设置其初始容量。它可以在以后超过此容量。可能是您在这个其他类中获得了IndexOutOfBoundsException,因为您尝试添加元素时使用的不是方法add(Object obj),而是方法add(int index,Object obj)。在这种情况下,当您提供超出当前数组边界的索引时,可能会出现这样的问题。或者您可能试图使用不存在(太大)的索引从数组中读取数据?否则,这个问题可能会被掩盖。请检查任何处理数组的代码。感谢您的反馈。从35秒到4.8秒似乎是一个很好的加速谢谢我也会试试这个。
private char[] readWholeFile(String file) {
Context ctx = ApplicationContextProvider.getContext();
int resId = ctx.getResources().getIdentifier(file, "raw", ctx.getPackageName());
InputStream inputStream = ctx.getResources().openRawResource(resId);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream), 8192);
try {
int length = inputStream.available();
char[] contents = new char[length];
reader.read(contents, 0, length);
return contents;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try {
if (reader != null) reader.close();
} catch (Exception e) {
}
}
}
public List<String> readEntries() {
final int EXPECTED_ELEMENTS = 24500;
char[] contents = readWholeFile("somefile");
if (contents == null) {
return new ArrayList<String>();
}
List<String> entries = new ArrayList<String>(EXPECTED_ELEMENTS);
String test;
BufferedReader reader = new BufferedReader(new CharArrayReader(contents));
try {
while ((test = reader.readLine()) != null) {
entries.add(test);
}
return entries;
} catch (IOException e) {
e.printStackTrace();
return new ArrayList<String>();
} finally {
try {
if (reader != null) reader.close();
} catch (Exception e) {
}
}
}