I doing encryption and decryption of document. Initially i read the file in byte array and passed that byte array to my encrypeted method. Upto 50MB size , i am able to encrypt the file without any issue. But if i increase my file SIZE to 80 MB , it is faling in cipher.doFinal() saying out of memoryException.
So how to encrypt bigger file without any issues? and also is doFinal() method have any size limitation. Please let me know.
and this is my code:
public String decrypt(byte[] file_encrypt) throws Exception {
String key22 = myKey;
byte[] b = key22.getBytes();
final SecretKey key = new SecretKeySpec(b, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/CBC/NoPadding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
final byte[] plainText = decipher.doFinal(file_encrypt);
try {
String dir = Environment.getExternalStorageDirectory() + File.separator + ".android";
String dir2 = Environment.getExternalStorageDirectory() + File.separator + ".android/.androidmain";
File folder = new File(dir); //folder name
File folder2 = new File(dir2); //folder name
if (!folder.exists())
folder.mkdirs();
if (!folder2.exists())
folder2.mkdirs();
File file = new File(Environment.getExternalStorageDirectory() + File.separator + ".android/.androidmain/file");
if (file.exists()) {
// Toast.makeText(contInst, "111", Toast.LENGTH_SHORT).show();
} else {
// Toast.makeText(contInst, "3333", Toast.LENGTH_SHORT).show();
file.createNewFile();
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bos.write(plainText);
bos.flush();
bos.close();
videoplay.setSource(Uri.fromFile(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return "ok";
}
When encrypting or decrypting, both the plain text and the encrypted text should be in the memory(RAM) at least one time.
But Java allow you to use limited memory. If you want to go from 50MB to 80MB, maybe using android:largeHeap=true in the application of your manifest will work. But if you want even a higher limit, you may want to perform the encryption by splitting up the file and performing encryption piece by piece.
Related
I am trying to save data into text file in the internal storage and read it again .. It works fine in my mobile with android 11 but when i tried at android 8 it gives me this error
java.io.FileNotFoundException:/data/user/0/com.example.example/test.txt
(No such file or directory)
It appears at the first time to open the activity but i can clear it - as normal text - and write a new text and save it so the file is there and usable
here is read code
File path = getApplicationContext().getFilesDir();
File readFrom = new File(path, fileName);
byte[] content = new byte[(int) readFrom.length()];
try {
FileInputStream stream = new FileInputStream(readFrom);
stream.read(content);
return new String(content);
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
and this write code
public void writeToFile(String fileName, String content) {
File path = getApplicationContext().getFilesDir();
try {
FileOutputStream writer = new FileOutputStream(new File(path, fileName));
writer.write(content.getBytes());
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I want to save bitmaps in the gallery.
Currently, I am using the following code:
public void saveBitmap(Bitmap output){
String filepath = Environment.getExternalStorageDirectory().toString() + "/Imverter/ImverterEffectedImage";
File dir = new File(filepath);
if(!dir.exists()){
dir.mkdir();
}
String fileName = "Imverter" + System.currentTimeMillis() + ".jpg";
File image = new File(dir, fileName);
try {
FileOutputStream fileOutputStream = new FileOutputStream(image);
output.compress(Bitmap.CompressFormat.JPEG, 80, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
It saves one single bitmap efficiently, but in my app, I have to deal with multiple bitmaps, and this method results in the slow output.
I want to store every single bitmap in a different files.
Thanks in advance.
I have an sqlite database which is written to from a service running on windows(C++). I am now trying to read from this same sqlite database which contains some blob data. I have some code as follows:
String tileQuery = "SELECT * FROM '" + layerName + "' WHERE zoom_level=?";
Cursor tileCursor = database.rawQuery(tileQuery, new String[] {zoom_level});
if( tileCursor.moveToFirst() )
{
while( !tileCursor.isAfterLast() )
{
int tileRow = tileCursor.getInt(tileCursor.getColumnIndex("tile_row"));
int tileColumn = tileCursor.getInt(tileCursor.getColumnIndex("tile_column"));
byte[] tileData = tileCursor.getBlob(tileCursor.getColumnIndex("tile_data"));
//Write tile to file
String fileName = layerName + "_" + zoom_level + "_" + tileRow + "_" + tileColumn + ".jpeg";
try {
/*
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + TILE_STORAGE_PATH + "/" + fileName));
bos.write(tileData);
bos.flush();
bos.close();
*/
ByteBuffer bb = ByteBuffer.wrap(tileData);
bb.order(ByteOrder.LITTLE_ENDIAN);
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + TILE_STORAGE_PATH + "/" + fileName);
byte[] toWrite = new byte[bb.remaining()];
bb.get(toWrite, 0 , toWrite.length);
fos.write(toWrite);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
tileCursor.moveToNext();
}
}
As shown, I am attempting to write the blobs to disk as jpeg images. No matter what I do, the images appear to be corrupt, as in I cannot view them on any image viewer within android. The same images can be written to file on windows and viewed correctly, which made me think that it was an endianess issue(due to the fact that the blob was written to the database via a service running on windows). I have tried changing the byte order and writing to disk again, but I get the same result. Could anyone suggest what I might be doing wrong/missing. Any help is greatly appreciated.
To make this work there are a few different steps. Assuming your database connection is working and those are the correct columns you are looking in with your Cursor
(1) Convert the blob to a Bitmap. You can use the blob you get back, assuming you actually downloaded and stored it to your local database, as the byte[] you will decode.
Bitmap bm = BitmapFactory.decodeByteArray(tileData, 0 ,tileData.length);
(2) Create a new file in the approprite directory and write to that file. You can do that with something like the code below. The idea is to get the local directory
private void storeBitmap(Bitmap myBitmap){
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/your_directory_name");
String fname = "your_file_name.jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
If you want to add the images to gallery or you just want a different (and potentially easier) way to add the file, look into using MediaScanner which will add the files as though you took the picture with your camers
I think I have looked at all of the relevant questions and I still can't get this to work.
Here is the code:
File sdCard = Environment.getExternalStorageDirectory();
File directory= new File (sdCard.getAbsolutePath() + appName);
directory.mkdirs();
File file = new File(directory,fileName);
The folder is created, but I get an error saying the file does not exist. appName is a string containing the name of the folder and that works correctly. fileName is a string containing the name of the file I want to include.
I have included the permission in the manifest.
What am I doing wrong?
Update:
The code tries to make a subdirectory and a file at the same time, which hidden because the code uses a named String rather than a String literal. Adding an intermediate step to create the subdirectory solved the problem.
If the directory is created, then you're on the right track. In your code you are not actually creating the file on the SD card. If you need to create the file, then do this:
File sdCard = Environment.getExternalStorageDirectory();
File file = new File(sdCard.getAbsolutePath() + appName + "/" + fileName);
directory.mkdirs();
file.createNewFile()
This is notional only. It would be much better to actually separate your fileName into a separate subfolder and the actual file and handle them separately.
Try this out:
In this I am creating a text file (.txt file) of a string.
public void createFileFromString(String text)
{
File logFile = new File("sdcard/xmlresponseiphone.txt");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Test this, and see what are you missing :)
Try with something like this. In this case I'm saving an image!
For creating the directory:
File directory = new File(Environment.getExternalStorageDirectory()
+ File.separator + appName);
directory.mkdirs();
And for saving into it
public void save(Bitmap graph, Context context, String name, String time, boolean now) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
graph.compress(Bitmap.CompressFormat.PNG, 100, bytes);
// you can create a new file name "test.jpg" in sdcard folder.
String fileName = "";
if (now){
fileName = getDateTime()+"_00"+".png";
}
else {
fileName = time.replace(".txt", ".png");
}
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "appName/" + fileName);
f.createNewFile(); // write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
}
I think the trick is in File.separator!
I have a web service that returns a jpg. I read this jpg into a byte[], convert to a Bitmap, and save it to the SD card. The next time the user comes to this Activity, it will search the SD card to see if the image exists before hitting the web service.
However, the code that checks the SD card returns a StreamCorruptedException if the file exists.
Here is my code that writes to the SD card:
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String root = Environment.getExternalStorageDirectory().toString();
new File(root + "/images").mkdirs();
try {
File file = new File(root + "/images", Integer.toString(intImageId) + "m.jpg");
FileOutputStream os = new FileOutputStream(file);
Bitmap theImageFromByteArray = BitmapFactory.decodeByteArray(image, 0, image.length);
theImageFromByteArray.compress(Bitmap.CompressFormat.JPEG, 80, os);
os.flush();
os.close();
}
catch (FileNotFoundException e) {
}
catch (IOException e) {
}
}
Here is my code that checks the SD card for the existing image:
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
|| Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
try {
File file = new File(Environment.getExternalStorageDirectory() + "/images", Integer.toString(mImageId) + "m.jpg");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
mImage = (Bitmap)ois.readObject();
ois.close();
}
catch (Exception e) {
}
}
The exception happens during new ObjectInputStream(fis)
You cannot arbitrarily readObject() like this. writeObject() needs to be used in order for readObject() to detect a valid serialized object.