Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
损坏的文件是使用FileInputStream和outstream生成的:java,android_Java_File Io_Android Sqlite_Inputstream_Outputstream - Fatal编程技术网

损坏的文件是使用FileInputStream和outstream生成的:java,android

损坏的文件是使用FileInputStream和outstream生成的:java,android,java,file-io,android-sqlite,inputstream,outputstream,Java,File Io,Android Sqlite,Inputstream,Outputstream,目前,我正在使用stream在我的应用程序中实现SQlite db备份功能。 当我备份数据库时,它工作正常,文件中有数据,我已经通过“SQlite数据库浏览器”对其进行了验证。但是,当尝试从我的应用程序的数据库路径通过FilOuputStream进行恢复,并从android SAF(存储访问框架)返回的UrI通过InputStream进行恢复时,指向我放置了db备份的外部存储,我得到了损坏的数据库文件,连接也被关闭 以下是我为此目的使用的两种方法 备份 //back db to a URI

目前,我正在使用stream在我的应用程序中实现SQlite db备份功能。 当我备份数据库时,它工作正常,文件中有数据,我已经通过“SQlite数据库浏览器”对其进行了验证。但是,当尝试从我的应用程序的数据库路径通过FilOuputStream进行恢复,并从android SAF(存储访问框架)返回的UrI通过InputStream进行恢复时,指向我放置了db备份的外部存储,我得到了损坏的数据库文件,连接也被关闭

以下是我为此目的使用的两种方法

备份

   //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;
}
恢复备份

  //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;
    }
}
日志


我不明白它为什么这样做,因为当我调试并在它工作的还原方法中放置断点时,这是非常奇怪的,请任何人帮助找出哪里出了问题

循环丢失了一些字节,所以我使用了filechannellike



循环丢失了一些字节,所以我使用了filechannellike



输入文件和输出文件在
backupDb
restoreBackup
中的大小相同。(只需File.length())尝试复制并关闭应用程序。那么数据库是否有效?标头似乎是正确的,因为前15个字节是53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00(根据),因此您可能遇到替换数据库和新数据库之间的冲突。或者,作为一个测试,还原到另一个DBname,打开该数据库,看看是否仍然存在问题,如果没有,那么非常确定替换的和新的冲突(缓存数据)。另一个问题可能是,如果数据库使用WAL,则-shm和/或-WAL文件包含数据。更多关于这个的信息。在
backupDb
restoreBackup
中,输入文件和输出文件的大小相同。(只需File.length())尝试复制并关闭应用程序。那么数据库是否有效?标头似乎是正确的,因为前15个字节是53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00(根据),因此您可能遇到替换数据库和新数据库之间的冲突。或者,作为一个测试,还原到另一个DBname,打开该数据库,看看是否仍然存在问题,如果没有,那么非常确定替换的和新的冲突(缓存数据)。另一个问题可能是,如果数据库使用WAL,则-shm和/或-WAL文件包含数据。更多关于这个。
    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;
    }
}