Android-Can';无法打开资产文件
我在资产文件夹中有一个sqlite文件。我使用的数据库管理器类在其他堆栈溢出文章中被引用了数千次: 问题在于open()方法(或getAssets?)不断抛出IOException。我的路径和文件名:Android-Can';无法打开资产文件,android,sqlite,Android,Sqlite,我在资产文件夹中有一个sqlite文件。我使用的数据库管理器类在其他堆栈溢出文章中被引用了数千次: 问题在于open()方法(或getAssets?)不断抛出IOException。我的路径和文件名: private static final String DB_NAME = "attractioninfo"; private static final String DB_PATH = "/data/data/seattle.tourists/"; 另一个相关的问题是关于路径。我已经检查了我的
private static final String DB_NAME = "attractioninfo";
private static final String DB_PATH = "/data/data/seattle.tourists/";
另一个相关的问题是关于路径。我已经检查了我的测试手机(三星galaxy sII)上的文件,但我没有看到a/data/data/mypackagename/。。。在任何地方这在内存中的具体位置?我使用的是安卓2.2
编辑:我做了更多的测试,我还发现在第一次安装时(这意味着手机内部存储上还没有数据库文件,需要复制到那里),这行代码也不起作用(我得到了一个SQLiteException)
完整代码:
package seattle.tourists;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "attractioninfo";
private static final String DB_PATH = "/data/data/seattle.tourists/databases/";
private static final int DB_VERSION = 1;
private static final String TABLE_NAME = "ExtraInfo";
private SQLiteDatabase db;
private final Context context;
/**
* Constructor
* @param context application context
*/
public DatabaseHelper( Context context ) {
super( context, DB_NAME, null, DB_VERSION );
this.context = context;
}
/**
* Creates empty database on system and rewrites it with existing database
* @throws IOException
*/
public void createDatabase() throws IOException {
boolean dbExist = checkDatabase();
if ( dbExist ) {
// do nothing, the database already exists;
}
else {
this.getReadableDatabase();
try {
copyDatabase();
}
catch ( IOException e ) {
throw new Error( "Error copying database" );
}
}
}
/**
* Check to see if a database exists
* @return true if database exists, false otherwise;
*/
private boolean checkDatabase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase( myPath, null, SQLiteDatabase.OPEN_READONLY );
}
catch ( SQLiteException e ) {
int x = 5;
}
if ( checkDB != null )
checkDB.close();
return checkDB != null ? true : false;
}
/**
* Copes database from assets-folder to system folder, where it can be
* accessed and handled. This is done by transferring byte-stream.
* @throws IOException
*/
private void copyDatabase() throws IOException {
// Open your local db as the input stream
AssetManager assets = context.getAssets();
InputStream myInput = assets.open( DB_NAME );
String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream( outFileName );
// transfer bytes from the inputfile to the outputfile
byte [] buffer = new byte[ 1024 ];
int length;
while ( ( length = myInput.read( buffer ) ) > 0 )
myOutput.write( buffer, 0, length );
// close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public SQLiteDatabase openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
return db = SQLiteDatabase.openDatabase( myPath, null, SQLiteDatabase.OPEN_READONLY );
}
public synchronized void close() {
if ( db != null )
db.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
// do nothing
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// do nothing
}
}
要从资产中打开数据库,请使用
AssetManager am = myContext.getAssets();
InputStream is = am.open("DB Name");
我的另一个相关问题是关于路径的。我已经检查了测试手机(三星galaxy sII)上的文件,但没有看到a/data/data/mypackagename/。
由于安全原因,您无法在设备上查看数据库。如果你真的想看看你的数据库。然后你需要在Emulator上安装你的应用程序
编辑:
复制数据库的代码
private static String db_path = "/data/data/your.package.name/databases/";
private static final String database_name = "search";
private void copyDataBase() throws IOException {
String outFileName = db_path + database_name+".db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int i, r;
AssetManager am = myContext.getAssets();
String fn = String.format(database_name);
InputStream is = am.open(fn);
while ((r = is.read(buffer)) != -1)
myOutput.write(buffer, 0, r);
is.close();
// Close the streams
myOutput.flush();
myOutput.close();
}
检查数据库
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = db_path + database_name+".db";
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
确保您已经添加了
在清单文件中,您发现我使用了错误的文件格式。我使用的是txt/SQL格式,而不是sqlite 在您的路径中: 私有静态最终字符串DB_PATH=“/data/data/settle.visters/”
包名后面缺少一个目录wc,即“/database/”。这与我的代码中的内容完全相同,只是我省略了AssetManager。已尝试AssetManager,但它不起作用。Naeem,感谢您的帮助。尝试了您的更改,但无效。我也会犯同样的错误。“无法加载数据库文件”和相同的异常。我正在写入外部存储吗?我以为我在给手机的内部存储器写信?
private static String db_path = "/data/data/your.package.name/databases/";
private static final String database_name = "search";
private void copyDataBase() throws IOException {
String outFileName = db_path + database_name+".db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int i, r;
AssetManager am = myContext.getAssets();
String fn = String.format(database_name);
InputStream is = am.open(fn);
while ((r = is.read(buffer)) != -1)
myOutput.write(buffer, 0, r);
is.close();
// Close the streams
myOutput.flush();
myOutput.close();
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = db_path + database_name+".db";
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}