0

我目前正在 Android Studio 中开发一个实现 AWS S3 的项目。S3 的用途是上传/存储我的本地 SQLite 数据库文件,以便我可以下载并在命令中使用它。我意识到这绝不是在 S3 中使用数据库的最佳方式。

我能够在我的 S3 存储桶中上传和下载文件。但是由于某种原因,根据 logcat,数据库文件已损坏。SQLite 数据库文件在下载时存储在设备的数据库文件夹中。

这是实现的代码:

public void uploadFile(String fileName) {
    File exampleFile = new File(getApplicationContext().getDatabasePath("Login.db").getPath());

    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(exampleFile));
        writer.append("Example file contents");
        writer.close();
    } catch (Exception exception) {
        Log.e("MyAmplifyApp", "Upload failed", exception);
    }

    Amplify.Storage.uploadFile(
        fileName,
        exampleFile,
        result -> Log.i("MyAmplifyApp", "Successfully uploaded: " + result.getKey()),
        storageFailure -> Log.e("MyAmplifyApp", "Upload failed", storageFailure)
    );
}

public void downloadFile() {
    Amplify.Storage.downloadFile(
        "Login.db",
        new File(getApplicationContext().getDatabasePath("Login.db") + ""),
        result -> Log.i("MyAmplifyApp", "Successfully downloaded: " + result.getFile().getName()),
        error -> Log.e("MyAmplifyApp",  "Download Failure", error)
    );
}

我正在寻找有关此问题的一些见解。我只是不确定是什么导致了文件损坏。我在想它可能是文件路径,但我相信它被正确导航。

4

1 回答 1

0

我怀疑您的问题是该文件实际上已损坏,并且可能是由于您使用writer.append("Example file contents");并保存了仅包含该文件的文件。

您也许可以添加代码在上传之前和下载文件之后进行一些检查。

以下是这样做的代码片段(在这种情况下,检查资产是否是有效的 sqlite 文件,它可能有点过头了):-

/**
 * DBHEADER
 * The the header string, the first 16 bytes, of the SQLite file
 *  This should never be changed.
 */
private static final String DBHEADER = "SQLite format 3\u0000"; // SQLite File header first 16 bytes

/**
 * Constants that represent the various stages of the copy
 */
private static final int
        STAGEOPENINGASSETFILE = 0,
        STAGEOPENINGDATABASEFILE = 1,
        STAGECOPYING = 3,
        STAGEFLUSH = 4,
        STAGECLOSEDATABSE = 5,
        STAGECLOSEASSET = 6,
        STAGEALLDONE = 100
                ;
/**
 * Constants for message codes
 */
private static final int
        MSGCODE_EXTENDASSETFILE_ADDEDSUBDIRECTORY = 20,
        MSGCODE_EXTEANDASSETFILE_EXTENDEDFILENAME = 21,
        MSGCODE_CHECKASSETFILEVALIDTY_OPENEDASSET = 30,
        MSGCODE_CHECKASSETFILEVALIDITY_OPENFILED = 31,
        MSGCODE_CHECKASSETFILEVALIDITY_NOTSQLITEFILE = 32,
        MSGCODE_CHECKASSETFILEVALIDITY_VALIDSQLITEFILE = 33,
        MSGCODE_COPY_FAILED = 40,
        MSGCODE_COPY_OK = 41
                ;

/**
 * The default buffer size, can be changed
 */
private static final int DEFAULTBUFFERSIZE = 1024 * 32; // 32k buffer

....


/**
 * Check that the asset file to be copied exists and optionally is a valid
 * SQLite file
 * @param cntxt                     The Context
 * @param extendedAssetFilename     The asset file name including subdirectories
 * @param showstacktrace            true id to show the stack-trace if an exception as trapped
 * @param checkheader               true if the SQLite file header should be checked
 * @return                          true if the checks are ok
 */
public static boolean checkAssetFileValidity(Context cntxt, String extendedAssetFilename, boolean showstacktrace, boolean checkheader) {
    boolean rv = true;
    InputStream is;
    try {
        is = cntxt.getAssets().open(extendedAssetFilename);
        messages.add(
                new Msg(
                        MSGCODE_CHECKASSETFILEVALIDTY_OPENEDASSET,
                        Msg.MESSAGETYPE_INFORMATION,
                        "Successfully Opened asset file " + extendedAssetFilename
                )
        );
        if (checkheader) {
            byte[] fileheader = new byte[DBHEADER.length()];
            is.read(fileheader,0,fileheader.length);
            if (!(new String(fileheader)).equals(DBHEADER)) {
                messages.add(
                        new Msg(
                                MSGCODE_CHECKASSETFILEVALIDITY_NOTSQLITEFILE,
                                Msg.MESSAGETYPE_ERROR,
                                "Asset file " +
                                        extendedAssetFilename +
                                        " is NOT an SQlite Database, instead found " + (new String(fileheader))
                        )
                );
                is.close();
                return false;
            } else {
                messages.add(
                        new Msg(
                        MSGCODE_CHECKASSETFILEVALIDITY_VALIDSQLITEFILE,
                                Msg.MESSAGETYPE_INFORMATION,
                                "Successfully validated asset file " + extendedAssetFilename +
                                        " . It has a valid SQLite Header."
                        )
                );
            }
        }
        is.close();
    } catch (IOException e) {
        messages.add(
                new Msg(
                        MSGCODE_CHECKASSETFILEVALIDITY_OPENFILED,
                        Msg.MESSAGETYPE_ERROR,
                        "Unable to open asset " + extendedAssetFilename + "."
                )
        );
        if (showstacktrace) {
            e.printStackTrace();
        }
        return false;
    }
    return rv;
}
  • 没有包含 Msg 类和相关方法,它们仅用于记录消息。如果要添加它们,请大声喊叫。

主要是检查标题。

于 2021-03-25T23:24:46.423 回答