0

在我的活动中,我创建了一个对象以将数据库从资产文件夹复制到应用程序数据库,在模拟器中一切正常,但在设备中,我没有得到这样的文件或目录错误

OutputStream os = new FileOutputStream(dbFile);

我需要许可:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

我调用 MainActivity:

db = new ExternalDB(this); 

在 ExternalDB 中(是 SqliteOpenHelper):

ExternalDB(Context context){
    super(context, DB_Name, null, DATABASE_VERSION);
    mycontext = context;
    AssetDatabaseOpenHelper adb = new AssetDatabaseOpenHelper(context,DB_Name);
    db = adb.OpenDatabase();
}

和 AssetDatabaseOpenHelper:

public class AssetDatabaseOpenHelper {

private static String DB_NAME;

private Context context;

AssetDatabaseOpenHelper(Context context, String DB_NAME){
    this.context = context;
    AssetDatabaseOpenHelper.DB_NAME = DB_NAME;
}

public SQLiteDatabase OpenDatabase(){
    File dbFile = context.getDatabasePath(DB_NAME);

    if(!dbFile.exists()){
        try{
            CopyDatabase(dbFile);
        }
        catch (IOException e){
            throw  new RuntimeException("Error Creating source database", e);
        }
    }

  //  copyDataBase();
    return SQLiteDatabase.openDatabase(dbFile.getPath(),null,SQLiteDatabase.OPEN_READWRITE);
}
private void CopyDatabase(File dbFile) throws IOException{
    InputStream is = context.getAssets().open(DB_NAME);
    OutputStream os = new FileOutputStream(dbFile);

    byte[] buffer = new byte[1024];

    while(is.read(buffer)>0){
        os.write(buffer);
    }
    os.flush();
    os.close();
    is.close();
}
}

正如我提到的,我在这一行得到了这个错误:

OutputStream os = new FileOutputStream(dbFile);
4

3 回答 3

1

CopyDatabaseget 在dbFile 不存在时被调用。正确的?然后你告诉FileOutputStream打开dbFile我们已经建立的不存在。因此,没有这样的文件或目录 Error。看起来是合法的,不是吗?

于 2018-07-11T11:28:14.730 回答
1

出现错误是因为文件夹“数据库”不存在,因此无法复制数据库

尝试:

  public SQLiteDatabase OpenDatabase() {
        File dbFile = context.getDatabasePath(DB_NAME);
        if (!dbFile.exists()) {
            try {

                //check if "databases" folder exists and create it if needed
                File destDir = context.getDatabasePath(DB_NAME).getParentFile();
                if(!destDir.exists()){
                    destDir.mkdirs();
                }

                CopyDatabase(dbFile);
            } catch (IOException e) {
                throw new RuntimeException("Error Creating source database", e);
            }
        } // copyDataBase();
        return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READWRITE);
    }
于 2018-07-11T19:23:03.370 回答
0

对于任何有同样问题的人,硬编码数据库路径对我不起作用,最后编写这样的复制函数解决了我的问题:

    /**
 * Copy database file from assets folder inside the apk to the system database path.
 * @param context Context
 * @param databaseName Database file name inside assets folder
 * @param overwrite True to rewrite on the database if exists
 * @return True if the database have copied successfully or if the database already exists without overwrite, false otherwise.
 */
private boolean copyDatabaseFromAssets(Context context, String databaseName , boolean overwrite)  {

    File outputFile = context.getDatabasePath(databaseName);
    if (outputFile.exists() && !overwrite) {
        return true;
    }

    outputFile = context.getDatabasePath(databaseName + ".temp");
    outputFile.getParentFile().mkdirs();

    try {
        InputStream inputStream = context.getAssets().open(databaseName);
        OutputStream outputStream = new FileOutputStream(outputFile);


        // transfer bytes from the input stream into the output stream
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }

        // Close the streams
        outputStream.flush();
        outputStream.close();
        inputStream.close();

        outputFile.renameTo(context.getDatabasePath(databaseName));

    } catch (IOException e) {
        if (outputFile.exists()) {
            outputFile.delete();
        }
        return false;
    }

    return true;
}

我必须先创建文件夹数据库,然后再尝试创建数据库文件。

从这个答案:https ://stackoverflow.com/a/29058717/4225644

于 2018-07-11T19:13:13.373 回答