设备上没有这样的文件或目录

时间:2018-07-11 11:12:36

标签: android sqlite

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

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);

3 个答案:

答案 0 :(得分:1)

CopyDatabase 不存在时,会呼叫

dbFile。对?然后,您告诉FileOutputStream打开我们已经建立的dbFile 不存在。因此,没有此类文件或目录错误。看起来合法,不是吗?

答案 1 :(得分:1)

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

尝试:

  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);
    }

答案 2 :(得分: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