简体   繁体   中英

Corrupted file is generated with FileInputStream and outstream : java, android

Currently I am working to implement a SQlite db backup feature in my application with stream. when I backup the database it works and the file has data as I have verified it through "Db browser for SQlite". But when try to restore through FilOuputStream from the database path of my application and InputStream from returned UrI by android SAF(Storage access framework) pointing to external storage where I have put db backup, I get corrupted database file and the connection is also closed.

following are the two methods I am using for this purpose

Taking Backup

   //back db to a URI
public synchronized static boolean backupDb(Context context, Uri uri, String dbNam) throws IOException {
    File dbFile = new File(context.getDatabasePath(dbNam).getPath());
    FileInputStream inFilStream = new FileInputStream(dbFile);
    OutputStream outFilStream = context.getContentResolver().openOutputStream(uri);//new FileOutputStream(backupFile);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inFilStream.read(buffer)) > 0) {
        outFilStream.write(buffer, 0, length);
    }
    outFilStream.flush();
    outFilStream.close();
    inFilStream.close();
    return true;
}

Restoring Backup

  //restore db from a URI
public static synchronized boolean restoreBackup(Context context, Uri uri, String dbNam) {
    try {
        InputStream inFilStream = context.getContentResolver().openInputStream(uri);
        File dbFile = new File(context.getDatabasePath(dbNam).getPath());
        FileOutputStream outFilStream = new FileOutputStream(dbFile);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inFilStream.read(buffer)) > 0) {
            outFilStream.write(buffer, 0, length);
            Log.wtf("db", "restoring backup up");
        }
        outFilStream.flush(); 
     // using outFilStream.getFD().sync(); also not working
        outFilStream.close();
        inFilStream.close();
        return true;
    } catch (IOException e) {
        return false;
    }
}

Log

在此处输入图片说明

I don't Understand why it is doing so as it is quite weird when I debug and put break points in the restore method it works, could any please help to figure out what is wrong there.

Looping missed some byte so I had used filechannel like

    public synchronized static boolean saveDbBackup(Context context, Uri uri, String dbNam) throws IOException {
    File dbFile = new File(context.getDatabasePath(dbNam).getPath());
    FileChannel inFilChannel = new FileInputStream(dbFile).getChannel();
    FileChannel outFilChannel = ((FileOutputStream)context.getContentResolver().openOutputStream(uri)).getChannel();//new FileOutputStream(backupFile);
    outFilChannel.transferFrom(inFilChannel,0,inFilChannel.size());
    outFilChannel.close();
    inFilChannel.close();
    return true;
}

public static synchronized boolean restoreDbBackup(Context context, Uri uri, String dbNam) {
    try {
        FileChannel inFileChannel= ((FileInputStream) context.getContentResolver().openInputStream(uri)).getChannel();
        FileChannel outFileChannel= new FileOutputStream(new File(context.getDatabasePath(dbNam).getPath())).getChannel();
        outFileChannel.transferFrom(inFileChannel,0,inFileChannel.size());
        outFilChannel.close();
        inFilChannel.close();
        return true;
    } catch (IOException e) {
        return false;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM