且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

下载游戏资源到SD卡上的Andr​​oid

更新时间:2023-02-02 19:17:26

您可以的加密与AES 的ZIP文件,但也将在提取资产的开销,这可能是一个问题,因为编写游戏时的表现通常是非常重要的。

You could encrypt the ZIP file with AES but there would an overhead in extracting the assets which might be a problem since performance is usually fairly important when writing a game.

不过,如你使用一个安全的加密称自己是不是真的值得的,因为如果有人真的感兴趣,他们可以在自己的应用程序的源$ C ​​$ C键。所以,你可以写一个的InputStream 的OutputStream 自己执行对ZIP文件的字节一些琐碎的翻译。这将是快速的读取文件时撤销,但将腐败,足以震慑人只是浏览通过他们的SD卡。ZIP文件

However, as you've said yourself using a secure encryption isn't really worthwhile since if someone's really interested they can find the keys in the source code of your application. So you could write an InputStream and OutputStream yourself to perform some trivial translation on the bytes of the ZIP file. This would be quick to undo when reading the file but would "corrupt" the ZIP file enough to deter someone just browsing through their SD card.

在使用它,你就会把你的数据流中的文件 ZIPInputStream ,例如之间:

When using it you'd put your stream in between the File and ZIPInputStream, e.g.:

File assets = new File(Environment.getExternalStorageDirectory(),"assets");
ZipInputStream zip = new ZipInputStream(new TranslateInputStream(assets));

作为一个例子翻译,你可以只XOR全部用一个已知值的字节数:

As an example translation, you could just XOR all the bytes with a known value:

private static final byte MAGIC_NUMBER = 13;

private void translateBuffer(byte[] buffer) {
    for (int i = 0;i < buffer.length;i++) {
        buffer[i] ^= MAGIC_NUMBER;
    }
}

private class TranslateOutputStream extends FileOutputStream {
    public TranslateOutputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public void write(int oneByte) throws IOException {
        oneByte ^= MAGIC_NUMBER;
        super.write(oneByte);
    }

    //In Android write(byte[]) calls this method so we don't need to override both        
    @Override
    public void write(byte[] buffer, int offset, int count)
            throws IOException {
        translateBuffer(buffer);
        super.write(buffer, offset, count);
    }
}

private class TranslateInputStream extends FileInputStream {

    public TranslateInputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public int read() throws IOException {
        return super.read() ^ MAGIC_NUMBER;
    }

    //In Android read(byte[]) calls this method so we don't need to override both        
    @Override
    public int read(byte[] buffer, int offset, int count)
            throws IOException {
        int bytesRead = super.read(buffer, offset, count);
        translateBuffer(buffer);
        return bytesRead;
    }
}

另外,你不能使用ZIP,你不关心COM pression。只是串联所有的资产集中在一个大的斑点。当你创建BLOB编写的每个资产的开始和结束位置出一个索引文件。索引文件将被包含在你的.apk文件,允许让你需要的在应用程序的大文件中的数据。由于大团块不会在标准格式的人将无法轻松地从中提取文件。要格外确保你总是可以垫与其他一些数据的文件的开头 - 也许只是一些纯文本 - 使斑点看起来像别的东西

Alternatively, you could not use ZIP as you don't care about compression. Just concatenate all the assets together in one large blob. As you create the blob write the start and end location of each asset out to an index file. The index file would then be included in your .apk file allowing to get the data you needed from the big file in your application. As the big blob wouldn't be in a standard format people wouldn't be able to easily extract files from it. To be extra sure you could always pad the beginning of the file with some other data - perhaps just some plain text - to make the blob look like something else.