我正在开发Android应用程序,我需要将视频保存在SD卡中,这不能转移,这就是为什么我在Facebook Conceal
需要时加密和解密的原因,如果视频大小为小。
每当我尝试对10MB
中不超过GenyMotion running 2.3.7
的大型视频文件进行加密和解密时,它会与OutOfMemoryException
崩溃,这意味着我的堆内存不足已分配给我申请无法处理但必须予以预防。
试过:
Facebook隐瞒:解密时说
You must read the entire stream to completion.
The verification is done at the end of the stream.
Thus not reading till the end of the stream will cause
a security bug. For safety, you should not
use any of the data until it's been fully read or throw
away the data if an exception occurs.
代码我正在使用Facebook Conceal
:
加密:
public void startEncryption() {
// Creates a new Crypto object with default implementations of
// a key chain as well as native library.
// Check for whether the crypto functionality is available
// This might fail if android does not load libaries correctly.
if (!crypto.isAvailable()) {
return;
}
OutputStream fileStream;
try {
File mEncryptedFile = new File(mPlainFile.getPath().substring(0,
mPlainFile.getPath().length() - 4)
+ "_encrypted"
+ mPlainFile.getPath().substring(
mPlainFile.getPath().length() - 4,
mPlainFile.getPath().length()));
fileStream = new BufferedOutputStream(new FileOutputStream(
mEncryptedFile));
// Creates an output stream which encrypts the data as
// it is written to it and writes it out to the file.
OutputStream outputStream;
outputStream = crypto.getCipherOutputStream(fileStream, entity);
outputStream.write(FileUtils.readFileToByteArray(mPlainFile));
// fileStream.flush();
// fileStream.close();
// outputStream.flush();
// outputStream.close();
// outputStream.flush();
File mRenameTo = new File(mPlainFile.getPath());
mPlainFile.delete();
mEncryptedFile.renameTo(mRenameTo);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CryptoInitializationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyChainException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
解密:
public String startDecryption() {
// Get the file to which ciphertext has been written.
try {
FileInputStream fileStream = new FileInputStream(mPlainFile);
// Creates an input stream which decrypts the data as
// it is read from it.
InputStream inputStream;
inputStream = crypto.getCipherInputStream(fileStream, entity);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// org.apache.commons.io.output.ByteArrayOutputStream out = new
// org.apache.commons.io.output.ByteArrayOutputStream(1024);
// Read into a byte array.
// int read;
// byte[] buffer = new byte[1024];
// // You must read the entire stream to completion.
// // The verification is done at the end of the stream.
// // Thus not reading till the end of the stream will cause
// // a security bug.
// int i = 0;
// while ((read = inputStream.read(buffer)) != -1) {
// out.write(buffer, 0, read);
// Log.i(TAG, "bytearrayoutputstream "+i++ + " "+read + " " +
// buffer.length + " "+out.size());
// }
mDecryptedFile = new File(mPlainFile.getPath().substring(0,
mPlainFile.getPath().length() - 4)
+ "_decrypted"
+ (mPlainFile.getPath().substring(mPlainFile.getPath()
.length() - 4, mPlainFile.getPath().length())));
OutputStream outputStream = new FileOutputStream(mDecryptedFile);
// IOUtils.copy(inputStream, outputStream);
try {
final byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1)
outputStream.write(buffer, 0, read);
outputStream.flush();
} catch (Exception e) {
} finally {
outputStream.close();
}
// out.writeTo(outputStream);
// out.flush();
// out.close();
// fileStream.close();
inputStream.close();
// outputStream.flush();
outputStream.close();
return mDecryptedFile.getPath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CryptoInitializationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyChainException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
是否有任何解决方案可以解决并加密和解密大型视频文件?
答案 0 :(得分:2)
看起来你正在将整个文件读入一个字节数组。您应该做的是创建一个输入流并将其提供给加密引擎。
所以这个:
outputStream.write(FileUtils.readFileToByteArray(mPlainFile));
应该看起来像你的解密循环。
BufferedInputStream bis = new BufferedInputStream(mPlainFile);
InputStream inputStream = crypto.getCipherInputStream(
bis,
entity);
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
不确定这是不是你最终的结果。我从文档中取出了加密解码。我认为这证实了他们的意图是说必须读取流直到结束。
答案 1 :(得分:0)
正如布鲁斯所强调的那样Encryption
上的瓶颈导致OutOfMemoryException
Decryption
时出现OutOfMemoryException
。这是我在加密和解密时执行的代码,不再导致fileStream = new BufferedOutputStream(new FileOutputStream(mEncryptedFile));
OutputStream outputStream;
outputStream = crypto.getCipherOutputStream(fileStream, entity);
int read;
byte[] buffer = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(newFileInputStream(mPlainFile));
while ((read = bis.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
outputStream.close();
bis.close();
。
加密:
InputStream inputStream;
inputStream = crypto.getCipherInputStream(fileStream, entity);
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStream outputStream = new FileOutputStream(mDecryptedFile);
BufferedInputStream bis = new BufferedInputStream(inputStream);
int mRead;
byte[] mBuffer = new byte[1024];
while ((mRead = bis.read(mBuffer)) != -1) {
outputStream.write(mBuffer, 0, mRead);
}
bis.close();
out.writeTo(outputStream);
inputStream.close();
outputStream.close();
out.close();
解密:
from bs4 import BeautifulSoup
soup = BeautifulSoup(data)
div = soup.find("div", class_="myself", title=True)
print(div["title"])