我在eclipse上开发Android应用程序到现在为止,现在我正在使用Mono for Android
。
我正在尝试从Assets文件夹中复制数据库,将其复制到SD卡上,然后从中读取数据。我正在使用以下代码。但是我收到数据库损坏错误。
运行以下代码后,SD卡上将创建空数据库,但实际表格未被复制。
如何检查MonoDevelop中的SD卡内容。我目前正在使用eclipse。
因为我刚刚开始进行Android开发,所以有任何帮助。
public class DbManager
{
private Context ctx;
private SQLiteDatabase mDb;
private DatabaseHelper dataHelper;
private String DATABASE_PATH = "/data/data/HelloM4A.HelloM4A/databases/";
private static String DATABASE_NAME = "CompanyMaster.db";
private SQLiteCursor cur;
private String[] b1;
private int x;
private static int DATABASE_VERSION = 1;
public DbManager(Context ctx)
{
this.ctx = ctx;
dataHelper = new DatabaseHelper(ctx);
}
private class DatabaseHelper : Android.Database.Sqlite.SQLiteOpenHelper
{
public DatabaseHelper AnyName
{ get; set; }
Context myContext = null;
public DatabaseHelper(Context context)
: base(context, DATABASE_NAME, null, DATABASE_VERSION)
{
this.myContext = context;
}
public override void OnCreate(Android.Database.Sqlite.SQLiteDatabase db)
{
}
public override void OnUpgrade(Android.Database.Sqlite.SQLiteDatabase db,
int oldVersion, int newVersion)
{
OnCreate(db);
}
}
public bool checkDataBase()
{
String myPath = DATABASE_PATH + DATABASE_NAME;
Java.IO.File f = new Java.IO.File(myPath);
return f.Exists();
}
public void createDataBase()
{
openDB();
try
{
Stream stream;
string destPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.Personal), "CompanyMaster.db");
if (new Java.IO.File(destPath).Exists())
using (stream = ctx.Assets.Open("CompanyMaster.db"))
{
OutputStream myOutput = new FileOutputStream(DATABASE_PATH +
DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = stream.Read(buffer, 0, 1024)) > 0)
{
myOutput.Write(buffer, 0, length);
}
if (mDb.IsOpen == true)
mDb.Close();
myOutput.Flush();
myOutput.Close();
stream.Close();
}
}
catch (Exception e)
{ }
}
public DbManager openDB()
{
try
{
mDb = dataHelper.WritableDatabase;
}
catch (Exception e)
{ }
return this;
}
public String[] getSymbol()
{
try
{
cur = (SQLiteCursor)mDb.RawQuery("select symbol, company_name " +
"from Scrip", null);
}
catch (SQLiteException e)
{ }
b1 = new String[2168];
x = 0;
if (cur.MoveToFirst())
{
do`
{
b1[x] = cur.GetString(cur.GetColumnIndex("symbol"));
x++;
}
while (cur.MoveToNext());
}
cur.Close();
return b1;
}
public void close()
{
mDb.Close();
}
}
经过各种建议,我尝试了以下代码:
public void createDataBase()
{
openDB();
try
{
var dataFile = ctx.ApplicationContext
.GetDatabasePath(DATABASE_NAME)
.AbsolutePath;
Console.WriteLine("path="+
ctx.ApplicationContext
.GetDatabasePath(DATABASE_NAME)
.AbsolutePath);
// I get path=/data/data/HelloM4A.HelloM4A/databases/CompanyMaster.db
// which is correct.
if (!System.IO.File.Exists(dataFile))
{
using (var input = ctx.Assets.Open(DATABASE_NAME))
using (var output = System.IO.File.Create(dataFile))
{
var buffer = new byte[1024];
int len;
while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
}
}
catch
{
}
}
public DbManager openDB()
{
try
{
mDb = dataHelper.WritableDatabase;
}
catch
{
}
return this;
}
现在的问题是,如果我在openDB()
中未使用createDataBase()
,则会fileNotFoundException
。
如果我在openDB()
中使用createDataBase()
,它会创建空数据库,因此DB不会被复制,因为条件if (!System.IO.File.Exists(dataFile))
,我将获得空白数据库作为最终输出。< / p>
由于已经创建了空DB,因此它不会遍历内部。
这里可以做些什么?
答案 0 :(得分:1)
我使用此代码将assets文件夹复制到我想要的位置(您应该能够修改它以适合自己):
const string dbName = "evolution.sqlite";
var dataDirectory = Path.Combine(ApplicationContext.FilesDir.AbsolutePath,
"databases");
var dataFile = Path.Combine(dataDirectory, dbName);
if (!Directory.Exists(dataDirectory))
{
Directory.CreateDirectory(dataDirectory);
}
if (!File.Exists(dataFile))
{
using (var input = ApplicationContext.Assets.Open(dbName))
using (var output = File.Create(dataFile))
{
var buffer = new byte[1024];
int len;
while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
}
注意:我动态创建路径,因为我使用的是ORM而不是DB帮助程序类。
您可以改为使用dataDirectory = context.GetDatabasePath("").AbsolutePath();
。
您必须在使用DatabaseHelper
之前执行此操作,因为数据库也将尝试创建数据库。我在Activity.OnCreate(...)
方法中执行此操作,然后使用DatabaseHelper
。
因此,如果我的代码位于名为CopyDB(...)的函数中,则使用以下方法:
public DbManager openDB()
{
CopyDB(...);
try
{
mDb = dataHelper.WritableDatabase;
}
catch(Exception e)
{
}
return this;
}