【问题标题】:Modify the bytes read by an InputStream while reading, not later在读取时修改 InputStream 读取的字节,而不是稍后
【发布时间】:2011-11-26 05:32:05
【问题描述】:

我需要做一个简单的加密,这样普通的最终用户就不能轻易访问一些文件。

FileInputStream 读取的文件是 html 文件、pngs、jpegs 和不同的简单文本文件(javascript、xml、...)

我现在做的是这样的:

public static byte[] toEncryptedByteArray(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    copy(input, output, true);
    return output.toByteArray();
}

public synchronized static final int copy(final InputStream input, final OutputStream output, final boolean modify) throws IOException {
    if (input == null || output == null) {
        throw new IOException("One stream is null!");
    }
    byte[] mBuffer = new byte[DEFAULT_BUFFER_SIZE];
    int count = 0;
    int n;
    while ((n = input.read(mBuffer)) != -1) {
        if (modify) {
            for ( int i = 0 ; i < n ; i++ ) {
                mBuffer[i] = (byte) ~mBuffer[i]; // byte manipulation
            }
        }
        output.write(mBuffer, 0, n);
        output.flush();
        count += n;
    }
    mBuffer = null;
    return count;
}

内存占用很大,因为我的内存中有完整的字节数组(我们谈论的是内存中 >2mb 的位图)。

我想我可以简单地扩展 FileInputStream 类并在读取文件内容时进行字节操作。这将减少内存使用量,因为我可以使用 Bitmap.decodeStream(inputstream) 而不是创建字节数组来从中获取位图......但在这里我完全被卡住了。 read()readBytes(...) 方法是原生的,所以我不能覆盖它们。

请在我的黑暗中传播光明...

【问题讨论】:

  • 只有 final 方法不能被覆盖。
  • read() 和 readBytes(...) 方法可能是原生的,但调用 super 并没有过时,我上次检查过。
  • @Dan 你能覆盖原生方法吗?我不这么认为...
  • 是的,这是可能的,因为我编写的代码就是这样做的。

标签: java android inputstream fileinputstream


【解决方案1】:

FileInputStream 不是你的问题。 read() 函数在每次调用时读取的内容不会超过 DEFAULT_BUFFER_SIZE。这是您对 ByteArrayOutputStream 的使用,它在您写入时占用了大量内存。

如果您想减少所需的内存量,那么我建议您直接写入 FileOutputStream 而不是 ByteArrayOutputStream。因此,当您从 InputStream 读取 DEFAULT_BUFFER_SIZE 时,加密并写入磁盘。

【讨论】:

  • 我没有将它保存在磁盘上。它已经加密保存在磁盘上。从磁盘读取时,我需要即时解密。由于我当前的实现在 InputStream 之外解密,我需要一个字节数组来执行解密。这就是我需要数组的原因。我会尝试像 CommonsWare 建议的那样包装它。
【解决方案2】:

流被设计为包装。这就是为什么你经常看到这样的行:

InputStream is=new BufferedInputStream(new FileInputStream(file));

因此,创建一个 DecryptingInputStream 来进行解密,并包裹另一个 InputStream

话虽如此,这并不难破解,因为任何反编译您的应用程序的人都可以轻松确定您的解密密钥和算法。

【讨论】:

  • 嗯,这种解密方式就是打乱sdcard上的文件。只是为了阻止普通用户从手机中复制文件。包装不会减少内存使用,对吧?我必须修改字节的方式是相同的。还是我错了?
  • @WarrenFaith:“包装不会减少内存使用,对吧?” -- 它将与覆盖方法一样多。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多