从资产文件夹读取sqlite文件

20

我正在开发一个应用程序,想要从项目的asset文件夹中读取一个sqlite数据库文件。我在网上搜索了一些资料,但没有找到有用的信息。请帮助我,谢谢!


5
你真的什么都没找到吗?网络太浪费时间了,来抽烟吧,走起! - Skynet
最好通过此链接进行查看:https://dev59.com/23E85IYBdhLWcg3wzWzM - Elshan
5个回答

13

您不能直接打开assets文件夹中的文件。相反,您需要将您的assets文件夹中的sqlite数据库复制到内部/外部存储器中,然后使用文件路径打开文件。尝试以下代码来读取来自assets的sqlite数据库并将其复制到sdcard以供使用。

public class DataBaseHelper extends SQLiteOpenHelper {
   private Context mycontext;
   private static String DB_NAME = "(datbasename).sqlite";
   private static String DB_PATH ="/data/data/"+BuildConfig.APPLICATION_ID+"/databases/";
   public SQLiteDatabase myDataBase;

public DataBaseHelper(Context context) throws IOException {
    super(context,DB_NAME,null,1);
    this.mycontext=context;
    boolean dbexist = checkdatabase();
    if (dbexist) {
        System.out.println("Database exists");
        opendatabase(); 
    } else {
        System.out.println("Database doesn't exist");
        createdatabase();
    }
}

public void createdatabase() throws IOException {
    boolean dbexist = checkdatabase();
    if(dbexist) {
        System.out.println(" Database exists.");
    } else {
        this.getReadableDatabase();
        try {
            copydatabase();
        } catch(IOException e) {
            throw new Error("Error copying database");
        }
    }
}   

private boolean checkdatabase() {

    boolean checkdb = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        File dbfile = new File(myPath);
        checkdb = dbfile.exists();
    } catch(SQLiteException e) {
        System.out.println("Database doesn't exist");
    }
    return checkdb;
}

private void copydatabase() throws IOException {
    //Open your local db as the input stream
    InputStream myinput = mycontext.getAssets().open(DB_NAME);

    // Path to the just created empty db
    String outfilename = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myoutput = new FileOutputStream(outfilename);

    // transfer byte to inputfile to 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 void opendatabase() throws SQLException {
    //Open the database
    String mypath = DB_PATH + DB_NAME;
    myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
}

public synchronized void close() {
    if(myDataBase != null) {
        myDataBase.close();
    }
    super.close();
}
}

如何使用这个类来读取数据库?如何运行查询?@GrlsHu - Usman Riaz
1
你只能在同一个类中编写查询代码。通过创建该类的实例调用方法来运行查询。@UsmanRiaz - GrIsHu
6
看起来这个解决方案是从https://dev59.com/23E85IYBdhLWcg3wzWzM#5949629复制的,但没有标注出处。 - shauvik
为什么我不能直接从资产中打开? - Pavel Poley

10
请使用 SQLiteAssetHelper,它包含了安装预打包数据库所需的所有代码,在您的应用程序第一次运行时可使用。

@UsmanRiaz:是的,它是一个 JAR 文件,你可以将其添加到你的项目中。 - CommonsWare
@CommonsWare 这个 jar 怎么使用?有什么想法吗? - Erum
这个类应该是一个装饰器或实用工具。因为现在有很多SQLiteOpenHelper的扩展,例如SQLiteCipher和ORMLite。 - S.D.

5
基本上,您可以从AssetManager打开函数获取文件名的InputStream,并将其写入OutputStream。
InputStream inputStream = getAssets().open(fileName);

如果您使用openOrCreateDatabase创建数据库,则可能希望将数据库放在databases文件夹中...
    String fileName = "MySQLiteDB.db";
    File file = getDatabasePath(fileName );
    if (!file.exists()) {
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdir();
        }

        InputStream inputStream = getAssets().open(DATABASE_NAME);
        OutputStream outputStream = new FileOutputStream(file);
        byte[] buffer = new byte[1024 * 8];
        int numOfBytesToRead;
        while((numOfBytesToRead = inputStream.read(buffer)) > 0)
        outputStream.write(buffer, 0, numOfBytesToRead);
        inputStream.close();
        outputStream.close();
    }

    db = SQLiteDatabase.openOrCreateDatabase(file, null);

1
在Kotlin中,你可以这样写:
val fileName = "your_file_name.db"
val file = getDatabasePath(fileName)

val data = SQLiteDatabase.openOrCreateDatabase(file, null)

然后你可以使用rawQuery来读取数据中的任何表。

-4
1. Make the SQLite database file.


    If you don't have a sqlite manager I recommend you to download the opensource SQLite Database Browser available for Win/Linux/Mac. Make database file.

    

2. Use this database in your Android application.

    Now put your database file in the "assets" folder of your project and create a Database Helper class by extending the SQLiteOpenHelper class


  //Constructor
  public Databasehelper(Context context)
  {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.myContext = context;
  }

  //Create a empty database on the system
  public void createDatabase() throws IOException
  {
        boolean dbExist = checkDataBase();

        if(dbExist)
        {
              Log.v("DB Exists", "db exists");
              // By calling this method here onUpgrade will be called on a
              // writeable database, but only if the version number has been
              // bumped
              //onUpgrade(myDataBase, DATABASE_VERSION_old, DATABASE_VERSION);
        }

        boolean dbExist1 = checkDataBase();
        if(!dbExist1)
        {
              this.getReadableDatabase();
              try
              {
                    this.close();    
                    copyDataBase();
              }
              catch (IOException e)
              {
                    throw new Error("Error copying database");
           }
        }
  }

  //Check database already exist or not
  private boolean checkDataBase()
  {
        boolean checkDB = false;
        try
        {
              String myPath = DATABASE_PATH + DATABASE_NAME;
              File dbfile = new File(myPath);
              checkDB = dbfile.exists();
        }
        catch(SQLiteException e)
        {
        }
        return checkDB;
  }

  //Copies your database from your local assets-folder to the just created empty database in the system folder
  private void copyDataBase() throws IOException
  {
        String outFileName = DATABASE_PATH + DATABASE_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        InputStream myInput = myContext.getAssets().open(DATABASE_NAME);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0)
        {
              myOutput.write(buffer, 0, length);
        }
        myInput.close();
        myOutput.flush();
        myOutput.close();
  }

  //delete database
  public void db_delete()
  {
        File file = new File(DATABASE_PATH + DATABASE_NAME);
        if(file.exists())
        {
              file.delete();
              System.out.println("delete database file.");
        }
  }

  //Open database
  public void openDatabase() throws SQLException
  {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
  }

  public synchronized void closeDataBase()throws SQLException
  {
        if(myDataBase != null)
              myDataBase.close();
        super.close();
  }

  public void onCreate(SQLiteDatabase db)
  {
  }

  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
  {    
        if (newVersion > oldVersion)
        {
              Log.v("Database Upgrade", "Database version higher than old.");
              db_delete();
        }
  }

//在此处添加插入、获取、删除和更新数据库数据的公共方法。 }

输入代码

ReferLink:http://androidtutorials60.blogspot.in/2013/03/1.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接