gpt4 book ai didi

android - 复制文件 : InputStream seems to be failing when trying to copy a DB out of the assets folder 时出错

转载 作者:行者123 更新时间:2023-11-29 18:35:35 24 4
gpt4 key购买 nike

我正在尝试将一个预加载的数据库从我的 Assets 文件夹复制到我可以从中读取的某个位置,但是当我的代码尝试调用 InputStream 以获取数据库时,我收到 IOException来自 Assets 文件夹。

我一直在关注 Reign Design 上的教程以及来自 SO 的出色回答:https://stackoverflow.com/a/9109728/3699923 .我的问题与 Error copying SQLite DB from Asset folder 极为相似,但是他得到了一个找不到文件的错误,而我的是一个更通用的“错误复制文件”

我还尝试从我的设备中删除该应用程序并再次测试以确保它与设备上已有的新文件无关。

我的 DBHelper 文件(这是一个摘录):

public class AppDataDBHelper extends SQLiteOpenHelper {

private static String TAG = "AppDataDBHelper"; // Tag just for the LogCat window
private static String DB_NAME ="appdata.db";// Database name
private static String DB_PATH = "";
private static String DB_TABLE = "Bonus_Data";
private static int DB_VERSION = 1;

private SQLiteDatabase mDataBase;
private final Context mContext;

public AppDataDBHelper(Context context) {
super(context, DB_NAME, null,DB_VERSION);
this.mContext = context;
DB_PATH = context.getAssets() + "/databases/";
// DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
Log.e(TAG,DB_PATH + DB_NAME);
}

public void createDataBase() throws IOException
{
//If the database does not exist, copy it from the assets.

Log.e(TAG,"Entered createDatabase");
boolean mDataBaseExist = checkDataBase();
if(!mDataBaseExist)
{
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assets
Log.e(TAG,"createDatabase passing to copyDatabase");
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
Log.e(TAG,"entered checkDatabase");
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}

//Copy the database from assets
private void copyDataBase() throws IOException
{
Log.e(TAG,"entered copyDatabase");
close();
Log.e(TAG,"copyDatabase close");
InputStream mInput = mContext.getAssets().open(DB_NAME);
Log.e(TAG,"copyDatabase inputStream");
String outFileName = DB_PATH + DB_NAME;
Log.e(TAG,DB_PATH + " | " + DB_NAME);
OutputStream mOutput = new FileOutputStream(outFileName);
Log.e(TAG,"copyDatabase outputStream");

FileHelper.copyFile(mInput, mOutput);
getWritableDatabase().close();
}

来 self 相关 Activity 文件的调用:

// Handle the appData DB.
SQLiteDatabase appDB = null;
appDBHelper = new AppDataDBHelper(this);

try {
Log.e(TAG,"Calling createDataBase");
appDBHelper.createDataBase();

} catch (IOException ioe) {
throw new Error("Unable to create database");
}

try {
Log.e(TAG,"Calling openDatabase");
appDBHelper.openDataBase();
} catch(SQLException sqle){
throw sqle;
}

我在 logcat 中看到的错误:

2019-02-02 22:40:29.103 603-603/net.tommyc.android.tourofhonor E/splashScreen: Going to Bonus List
2019-02-02 22:40:29.170 603-603/net.tommyc.android.tourofhonor D/ScrollView: initGoToTop
2019-02-02 22:40:29.195 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: android.content.res.AssetManager@9353a47/databases/appdata.db
2019-02-02 22:40:29.195 603-603/net.tommyc.android.tourofhonor E/bonusListing: Calling createDataBase
2019-02-02 22:40:29.195 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: Entered createDatabase
2019-02-02 22:40:29.195 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: entered checkDatabase
2019-02-02 22:40:29.224 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: createDatabase passing to copyDatabase
2019-02-02 22:40:29.224 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: entered copyDatabase
2019-02-02 22:40:29.224 603-603/net.tommyc.android.tourofhonor E/AppDataDBHelper: copyDatabase close
2019-02-02 22:40:29.224 603-603/net.tommyc.android.tourofhonor D/AndroidRuntime: Shutting down VM
2019-02-02 22:40:29.225 603-603/net.tommyc.android.tourofhonor E/AndroidRuntime: FATAL EXCEPTION: main
Process: net.tommyc.android.tourofhonor, PID: 603
java.lang.Error: ErrorCopyingDataBase
at net.tommyc.android.tourofhonor.AppDataDBHelper.createDataBase(AppDataDBHelper.java:57)
at net.tommyc.android.tourofhonor.bonusListing.onCreate(bonusListing.java:53)
at android.app.Activity.performCreate(Activity.java:7183)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

最佳答案

[更新:测试好的代码]我已将代码从复制数据库更新为从数据库表中读取一组名称。

为了访问存储在 assets 文件夹中的外部 sqlite 数据库,这对我有用,所以请检查一下。

data inserted into external sqlite database but not saving in android studio

对于您的情况,我建议进行以下更改:

1) 我在 sqlite dbbrowser 中的表:

CREATE TABLE `Bonus_Data` (
`id` INTEGER NOT NULL,
`name` TEXT NOT NULL,
PRIMARY KEY(`id`)
);

2) 在您的 AppDataDBHelper 类中:

public class AppDataDBHelper extends SQLiteOpenHelper{
private static String TAG = "AppDataDBHelper"; // Tag just for the LogCat window
private static String DB_NAME = "appdata.db";// Database name
private static String DB_TABLE = "Bonus_Data";
private static int DB_VERSION = 1;

private SQLiteDatabase mDataBase;
private final Context mContext;

public AppDataDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.mContext = context;
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

public void createDataBase() throws IOException {
//If the database does not exist, copy it from the assets.

Log.e(TAG, "Entered createDatabase");
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getReadableDatabase();
this.close();
try {
//Copy the database from assets
Log.e(TAG, "createDatabase passing to copyDatabase");
copyDataBase();
Log.e(TAG, "createDatabase database created");
} catch (IOException mIOException) {
throw new Error("ErrorCopyingDataBase");
}
}
}

//Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase() {
Log.e(TAG, "entered checkDatabase");
File dbFile = new File(mContext.getDatabasePath(DB_NAME).getPath());
if (dbFile.exists()) return true;
File dbdir = dbFile.getParentFile();
if (!dbdir.exists()) {
dbdir.mkdirs();
}
return false;
}

//Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = null;
OutputStream mOutput = null;
Log.e(TAG, "entered copyDatabase");
Log.e(TAG, "copyDatabase close");
String outFileName = mContext.getDatabasePath(DB_NAME).getPath();

try {
mInput = mContext.getAssets().open(DB_NAME);
mOutput = new FileOutputStream(outFileName);

byte[] buffer = new byte[1024];
int length;
while ((length = mInput.read(buffer)) > 0) {
mOutput.write(buffer, 0, length);
}
mOutput.flush();
mOutput.close();
mInput.close();
} catch (IOException ie) {
throw new Error("Copydatabase() error ");
}
}

public ArrayList<String> readNames() {
boolean distinct = true;

ArrayList<String> mname = new ArrayList<>();

String[] columns = new String[]{"name"};
//Cursor cursor = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
//This is used to draw distinct data values from database table
Cursor cursor = mDataBase.query(distinct, DB_TABLE, columns, null, null, null, null, null, null);
int iName = cursor.getColumnIndex("name");

for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
mname.add(cursor.getString(iName));
}

cursor.close();
return mname;
}
//this openRead is needed everytime you access this helper class
public void openRead() {
mDataBase = getReadableDatabase(); //mDatabase should always be initialized or else app crashes while accessing TABLE
}
}

2) 最后在您的 Activity 的 onCreate() 方法中创建数据库:

public class TestActivity extends AppCompatActivity {

private static final String TAG = "TestActivity";
private ArrayList<String> name = new ArrayList<>();
private TextView textView_name;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

AppDataDBHelper appDBHelper = new AppDataDBHelper(this);
try {
Log.e(TAG, "Calling createDataBase");
appDBHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to CREATE DATABASE");
} finally {
appDBHelper.close();
}

textView_name = findViewById(R.id.textView_name);

check();
String message = "";
for (int i=0; i<name.size(); i++) {
message = message + name.get(i) + "\n";
}
textView_name.setText(message);
}

private void check() {
try {
AppDataDBHelper appDataDBHelper = new AppDataDBHelper(this);
appDataDBHelper.openRead(); //without this app crashes
name = appDataDBHelper.readNames();
appDataDBHelper.close();
} catch (Exception e) {
throw new Error("error reading");
}
}
}

关于android - 复制文件 : InputStream seems to be failing when trying to copy a DB out of the assets folder 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54500706/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com