如果我在应用程序启动时只读取一次文件并将其内容放入字符串数组中,这会是一个好主意吗?我不确定数组是否能处理这么多数据。否则,什么是正确的模式?
感谢您的阅读。
将其存储为CSV(逗号分隔值)。打开读取流,定位到随机位置并读取一小块字符,直到您两次遇到','
。现在,从您已读取的字符串中提取逗号之间的单词。此外,您可以使用自定义分隔符,例如'#'或'|',而不是逗号。
更新:使用{{link1:RandomAccessFile
}}。
更新2:如果您每行存储一个单词,即用\n
分隔,则{{link2:readLine()
}}会使此过程更加容易。
这里有一些需要注意的事项:
如果你的应用程序从SD卡中读取数据,SD卡的质量实际上是一个因素 - 根据你使用的SD卡的等级,有不同的读写速度 - 查一下。
你提到每次点击生成时都会随机选择文件中的一行 - 由于可以确定用户会多次点击生成,所以将该文件读取一次,将内容存储在某个地方(sqlite),下次需要获取随机单词时,从存储的数据中获取。这样,你将限制从外部存储器(在移动标准中,这是一个繁重的任务)读取的次数为每个应用程序启动一次。
你甚至可以在文件中放置一个标记,以便让你知道内容是否发生了变化。从随机字符串到当前日期再到md5校验和,任何东西都可以让你知道你不需要再次读取文件,因为你之前已经读取过并将内容存储在sqlite数据库中。你想把这个标记放在文件的第一行。
现在其他人都告诉你考虑写入sqlite数据库,甚至复制一个.db文件本身(可以单独生成),选择一个随机项将会很简单。我更愿意警告你在数据库中写入36万条记录。使用默认的ContentProvider insert(Uri, ContentValues)
方法可以工作,但我不会感到惊讶,如果这比解析文件本身花费的时间更长。这里的诀窍是重写ContentProvider的bulkInsert(Uri, ContentValues[])
方法,使用编译好的语句。默认实现只是多次调用insert
方法,因此每次插入都会打开和关闭SqliteDatabase对象。你要做的是在顶部调用beginTransaction
,有一个for循环来insert
每个ContentValues中的项,然后调用setTransactionSuccessful
,最后调用endTransaction
。
private class YourTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... s) {
//Here you have to make the loading / parsing tasks
//Don't call any UI actions here. For example a Toast.show() this will couse Exceptions
// UI stuff you have to make in onPostExecute method
}
@Override
protected void onPreExecute() {
// This method will called during doInBackground is in process
// Here you can for example show a ProgressDialog
}
@Override
protected void onPostExecute(Long result) {
// onPostExecute is called when doInBackground finished
// Here you can for example fill your Listview with the content loaded in doInBackground method
}
}
new YourTask().execute("");
在这里你可以了解更多关于AsyncTasks的内容: