【问题标题】:Copy database file to local storage将数据库文件复制到本地存储
【发布时间】:2019-08-13 01:13:30
【问题描述】:

我在assete文件夹中有一个sqlite数据库。

我想把它复制到本地存储。

我使用此代码,它复制没有表的数据库。当我想在 sqlliteeditor 中打开数据库时,出现错误 14。

  private void copyDataBase2() throws IOException {
    OutputStream os = new FileOutputStream(  "/data/data/pakagename/Learning.db");
    InputStream is = context.getAssets().open("databases/Learning.db");
    byte[] buffer = new byte[1024];
    int length;
    while ((length = is.read(buffer)) > 0) {
        os.write(buffer, 0, length);
    }
    is.close();
    os.flush();
    os.close();
}

【问题讨论】:

    标签: android sqlite local-storage


    【解决方案1】:

    尝试像这样复制数据库文件:

    public class DbHelper extends SQLiteOpenHelper {
        private static String DB_PATH = new File(getFilesDir(), "databases").getPath();
        private static String DB_NAME = "test_db.db";
        private SQLiteDatabase dataBase;
        private final Context fContext;
        public DbHelper(Context context) {
            super(context, DB_NAME, null, 1);
            this.fContext = context;
        }
        public void createDataBase() throws IOException {
            boolean dbExist = checkDataBase();
            if (dbExist) {
                //ничего не делаем – файл базы данных уже есть
            } else {
                this.getReadableDatabase();
                try {
                    copyDataBase();
                } catch (IOException e) {
                    throw new Error("Error copying database");
                }
            }
        }
        private boolean checkDataBase() {
            SQLiteDatabase checkDB = null;
            try {
                String myPath = DB_PATH + DB_NAME;
                checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
            } catch (SQLiteException e) {
                //файл базы данных отсутствует
            }
            if (checkDB != null) {
                checkDB.close();
            }
            return checkDB != null ? true : false;
        }
        private void copyDataBase() throws IOException {
            InputStream input = fContext.getAssets().open(DB_NAME);
            String outFileName = DB_PATH + DB_NAME;
            OutputStream output = new FileOutputStream(outFileName);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            output.flush();
            output.close();
            input.close();
        }
        public void openDataBase() throws SQLException {
            String path = DB_PATH + DB_NAME;
            dataBase = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        }
        @Override
        public synchronized void close() {
            if (dataBase != null)
                dataBase.close();
            super.close();
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
    

    如果您使用 API 19 或更高版本:

    String db_path = fContext.getDatabasePath(DB_NAME);
    

    当我想在 sqlliteeditor 中打开数据库时,出现错误 14。

    我还建议您检查数据库文件。如果在编辑器中打开出现错误,很有可能问题不在文件复制算法上。

    【讨论】:

    • @ar.gorgin,我也建议你检查数据库文件。如果在编辑器中打开出现错误,很有可能问题不在文件复制算法上。
    • 当我用navicat打开时,它没有错误。使用此代码,复制没有表的数据库
    • 不要硬编码“/data/data/com.example.dbreadytest/databases/”的东西。它可以在多用户或容器环境中更改。使用new File(getFilesDir(), "databases").getPath() 或其他东西。
    • 谢谢,使用时出现错误java.io.FileNotFoundException: /data/data/'domain name'/files/databases/Learning.db: open failed: ENOENT (No such file or directory)
    【解决方案2】:

    这只是文件复制,它是数据库还是什么都没关系。实际上上面的代码不知道表,因此没有表没有复制数据库的能力。

    您可以比较两个 db 文件的哈希码。为此,您可以更改代码以将文件复制到外部存储而不是应用的数据目录现在。然后通过 adb 将文件检索回 PC 并进行比较。

    根据您的代码,没有问题,它们应该是相同的。

    很可能(或者)db 文件本身已损坏(或者)您以错误的方式打开它。

    【讨论】:

      【解决方案3】:

      试试这个:

      private void copyDB(Context context) throws Exception{
          File destinationDirectory = new File(Environment.getExternalStorageDirectory() + "/Destination/");
          File destinationFile = new File(destinationDirectory + "/myDatabase.db");
          if (!destinationDirectory.isDirectory()) {
              destinationDirectory.mkdir();
              destinationFile.createNewFile();
          }
          File dbFile = context.getDatabasePath("my_database.db");
          if (dbFile.exists()) {
              copyFile(dbFile.getPath(), logFile.getAbsolutePath(), false);
          }
      }
      
      private boolean copyFile(String sPath, String dPath, boolean isDeleteSourceDir) {
          FileInputStream fis = null;
          FileOutputStream fos = null;
          try {
              File sourceFile = new File(sPath);
              fis = new FileInputStream(sourceFile);
              File dir = new File(dPath);
              if (!dir.exists()) {
                  dir.mkdirs();
              }
              File outfile = new File(dPath);
              outfile.delete();
              if (!outfile.exists()) {
                  outfile.createNewFile();
              }
              fos = new FileOutputStream(outfile);
              byte[] block = new byte[1000];
              int i;
              while ((i = fis.read(block)) != -1) {
                  fos.write(block, 0, i);
              }
              fos.close();
              if (isDeleteSourceDir) {
                  deleteDirectory(new File(sPath));
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          } finally {
              fis.close();
              fos.close();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-28
        • 2016-12-30
        • 2021-08-18
        • 2020-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-06
        • 1970-01-01
        相关资源
        最近更新 更多