I'm trying to store a Map into android's internal storage.
My code:
private void saveFavorite(){
LinkedHashMap<String, LinkedList<MyCustomObject>> favorites = new LinkedHashMap<String, LinkedList<MyCustomObject>>();
try{
InputStream file = openFileInput(PATH);
BufferedInputStream buffer = new BufferedInputStream( file );
ObjectInput input = new ObjectInputStream ( buffer );
try{
Object o = input.readObject();
if(o instanceof LinkedHashMap<?, ?>)
favorites = (LinkedHashMap<String, LinkedList<MyCustomObject>>)o;
}
finally{
input.close();
}
}
catch(ClassNotFoundException ex){
}
catch(IOException ex){
}
String favoriteName = "asd";
favorites.put(favoriteName, myobject);
FileOutputStream fos;
try {
fos = openFileOutput(PATH, MODE_APPEND);
BufferedOutputStream buffer = new BufferedOutputStream( fos );
ObjectOutput output = new ObjectOutputStream( buffer );
try{
output.writeObject(favorites);
}finally{
output.close();
}
}catch(IOException ex){
}
}
MyCustomObject implements Serializable
While debugging I don't see any problem. It seems it reads an empty map, then writes the map with a value but when I read it again, map is empty.
Help please.
UPDATE:
I have found inside /data/data/my_project_package_structure/files/
a file called like my var PATH. It's growing in size each time I call my save method so I think it writes well but I don't know what I'm doing wrong.
try {
**fos = openFileOutput(PATH, MODE_APPEND);**
BufferedOutputStream buffer = new BufferedOutputStream( fos );
Should be
**fos = openFileOutput(PATH, MODE_PRIVATE);**
Related
I want to encrypt video files stored in SD card
Environment.getExternalStorageDirectory()
I have found that Facebook conceal is good for encrypting large files. I have followed this tutorial Make fast cryptographic operations on Android with Conceal
Here is what i have done up to now.
Encryption method
public void encodeAndSaveFile(File videoFile, String path) {
try {
final byte[] encrypt = new byte[(int) videoFile.length()];
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir(path, Context.MODE_PRIVATE);
File mypath = new File(directory, "en1");
Crypto crypto = new Crypto(new SharedPrefsBackedKeyChain(this), new SystemNativeCryptoLibrary());
if (!crypto.isAvailable()) {
return;
}
OutputStream fileStream = new BufferedOutputStream(
new FileOutputStream(mypath));
OutputStream outputStream = crypto.getCipherOutputStream(
fileStream, new Entity("Passwordd"));
outputStream.write(encrypt);
outputStream.close();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(WebViewActivity.this,"Encrypted",Toast.LENGTH_LONG).show();
}
Decryption method
private void decodeFile(String filename,String path) {
Crypto crypto = new Crypto(new SharedPrefsBackedKeyChain(this),
new SystemNativeCryptoLibrary());
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir(path, Context.MODE_PRIVATE);
File file = new File(directory, filename);
try {
FileInputStream fileStream = new FileInputStream(file);
InputStream inputStream = crypto.getCipherInputStream(fileStream,
new Entity("Password"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int read;
byte[] buffer = new byte[1024];
while ((read = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(WebViewActivity.this,"Decrypted",Toast.LENGTH_LONG).show();
}
But this code throwing following error at the run time
java.lang.illegalArgumentException: File contains a path separator
Then i have changed "mypath: variable of encodeAndSaveFile to this
File mypath = new File(directory, "en1");
and "file" variable of decodeFile to this
File file = new File(directory, filename);
Then no errors but. Encryption is not happening. Please help to solve this or suggest correct method for video encryption with conceal lib.
I have put in place the ability to archive user data for my application by creating a compressed file.
I create the compressed file like this :
try
{
int iBufferSize = 2048;
int iByteCount = 0;
byte btData[] = new byte[iBufferSize];
File fZipFile = new File(ARCHIVE_FILE);
FileOutputStream fos = new FileOutputStream(fZipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
BufferedInputStream bis = null;
FileInputStream fIn = null;
ZipEntry ze = null;
File[] fPartitions = new File(FILES_PATH).listFiles();
for(File fPartition : fPartitions)
{
lFileSize = fPartition.length();
fIn = new FileInputStream(fPartition);
bis = new BufferedInputStream(fIn, iBufferSize);
ze = new ZipEntry(fPartition.getName());
ze.setSize(lFileSize);
zos.putNextEntry(ze);
while((iByteCount = bis.read(btData, 0, iBufferSize)) != -1)
{
zos.write(btData, 0, iByteCount);
}
bis.close();
zos.closeEntry();
}
zos.close();
bis.close();
fIn.close();
bOk = true;
}
catch(Exception e)
{
e.printStackTrace();
}
Now, when I try to restore the contents, I am not able to get the original file size. Here is how I am doing the expansion :
try
{
// open the archive
FileInputStream fis = new FileInputStream(fArchive);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
bBuffer = new byte[2048];
// iterate through all files, putting them back into the same place
ze = zis.getNextEntry();
while(ze != null)
{
strFileName = ze.getName();
strFileName = FILE_PATH + "/" + strFileName;
fCheck = new File(strFileName);
lZipFileSize = ze.getSize(); // <--- returns -1 systematically
lTargetFileSize = fCheck.length();
fCheck = null;
FileOutputStream fos = new FileOutputStream(strFileName);
// read the data
while((iCount = zis.read(bBuffer)) != -1)
{
fos.write(bBuffer, 0, iCount);
}
fos.close();
ze = zis.getNextEntry();
}
zis.close();
fis.close();
bOk = true;
}
catch(Exception e)
{
e.printStackTrace();
}
I have noted that ze.getSize() is returning -1 systematically.
How can I store and get the individual file sizes ?
Ok, so if you come across this problem, here is how I worked around it.
Use the ZipFile class for reading the zip file.
Inspired from ZipInputStream: getting file size of -1 when reading and The ZipFileTest.java Android example source code
I am new to android development. Currently, i am developing a simple app for writing and reading a String Array to an internal storage.
First we have A array then save them to storage, then next activity will load them and assign them to array B. Thank you
To write to a file:
try {
File myFile = new File(Environment.getExternalStorageDirectory().getPath()+"/textfile.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.write("replace this with your string");
myOutWriter.close();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
To read from the file:
String pathoffile;
String contents="";
File myFile = new File(Environment.getExternalStorageDirectory().getPath()+"/textfile.txt");
if(!myFile.exists())
return "";
try {
BufferedReader br = new BufferedReader(new FileReader(myFile));
int c;
while ((c = br.read()) != -1) {
contents=contents+(char)c;
}
}
catch (IOException e) {
//You'll need to add proper error handling here
return "";
}
Thus you will get back your file contents in the string "contents"
Note: you must provide read and write permissions in your manifest file
If you wish to store yourObject to cache directory, this is how you do it-
String[] yourObject = {"a","b"};
FileOutputStream stream = null;
/* you should declare private and final FILENAME_CITY */
stream = ctx.openFileOutput(YourActivity.this.getCacheDir()+YOUR_CACHE_FILE_NAME, Context.MODE_PRIVATE);
ObjectOutputStream dout = new ObjectOutputStream(stream);
dout.writeObject(yourObject);
dout.flush();
stream.getFD().sync();
stream.close();
To read it back -
String[] readBack = null;
FileInputStream stream = null;
/* you should declare private and final FILENAME_CITY */
inStream = ctx.openFileInput(YourActivity.this.getCacheDir()+YOUR_CACHE_FILE_NAME);
ObjectInputStream din = new ObjectInputStream(inStream );
readBack = (String[]) din.readObject(yourObject);
din.flush();
stream.close();
On Android you have several storage options.
If you want to store a string array, use SharedPreferences:
This post might be a solution.
private void copyMB() {
AssetManager assetManager = this.getResources().getAssets();
String[] files = null;
try {
files = assetManager.list(assetDir);
} catch (Exception e) {
e.printStackTrace();
}
for(int i=0; i<files.length; i++) {
InputStream in = null;
FileOutputStream fos;
try {
in = assetManager.open(assetDir+"/" + files[i]);
fos = openFileOutput(files[i], Context.MODE_PRIVATE);
copyFile(in, fos);
in.close();
in = null;
fos.flush();
fos.close();
fos = null;
} catch(Exception e) {
e.printStackTrace();
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
My problem is that UTF-8 character such as åäö is replaced by wierd looking characters. How can I make sure that it my InputStream reader uses UTF-8? In normal Java it would be easy Writing … new InputStreamReader(filePath, "UTF-8"); But since I am getting it from the Asset folder I canot do that (I have to use the assetManager.open() method which wont take "UTF-8" as an argument.
Any ideas? :)
Thank you for your help.
As you write yourself:
new InputStreamReader(in, "UTF-8");
creates a new stream reader with Utf-8 encoding. Just put it in the copyFile() method with your InputStream as the argument.
You can do like this as well:
new InputStreamReader(is, StandardCharsets.UTF_8)
I'm tired messing around.
And i'm beginning to believe that it actually isn't possible.
Where do i find a simple example showing how to write a file "myPath/myFile.txt"?
And then reading it back again?
This an example of a code block that i can't get to work:
if(pathExists(path, ctx))
{
File file = new File(ctx.getFilesDir().getAbsolutePath() +"/" + path, fileName);
FileInputStream fIn = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fIn);
StringWriter writer = new StringWriter();
IOUtils.copy(fIn, writer, "UTF-8");
fileStr = writer.toString();
}
This is the error that i get:
"java.io.IOException: Is a directory"
This following snippet will copy you files which are saved in the application space to your desired path.
File mfile=new File("/data/data/src.com.file.example/files");
File[] list=mfile.listFiles();
// The path where you like to save your files
String extStorageDirectory = "/mnt/sdcard/backup/";
File file23 = null;
File fr = null;
for(int i =0;i<list.length;i++){
File myNewFolder = new File(extStorageDirectory +list[i].getName().substring(0,5));
if(myNewFolder.exists()){
String selectedFilePathq = "data/data/src.com.file.example/file/"+list[i].getName();
file23 = new File(selectedFilePathq);
fr = new File(myNewFolder+"/"+list[i].getName());
}else{
myNewFolder.mkdir();
String selectedFilePathq = "data/data/src.com.file.example/files /"+list[i].getName();
file23 = new File(selectedFilePathq);
fr = new File(myNewFolder+"/"+list[i].getName());
}
try {
copy(file23,fr);
} catch (IOException e) {
e.printStackTrace();
}
}
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
You could not write to Android internal storage (not unless your device is rooted) aside from the private file space assigned to your own application by the android system.
String strfile1 = getApplicationContext().getFilesDir().getAbsolutePath() + "/serstatus.txt" ;
File f1 = new File(strfile1);
you have to use serialization methods as in java.
to save an text as file you should be using FileOutputStream and to read the file you should be using FileInputStream. You can check the following code it has a simple edittext and two buttons one to save and one to read data saved in that file.
The following code is to save text in the file named raksi.
Button savebutton = (Button)findViewById(R.id.but);
savebutton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
e= (EditText)findViewById(R.id.edit);
StringBuffer sb = new StringBuffer();
sb.append(e.getText().toString());
String s = sb.toString();
try {
final String TESTSTRING = new String(s);
FileOutputStream fOut = openFileOutput("raksi.txt",MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write(TESTSTRING);
ll = TESTSTRING.length();
osw.flush();
osw.close();
}catch (Exception e) {
// TODO: handle exception
}
}
});
The following code is the click listener for the button get. it reads the data from the file and displays as toast,
Button b1 = (Button)findViewById(R.id.but1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
FileInputStream fIn = openFileInput("name.txt");
InputStreamReader isr = new InputStreamReader(fIn);
char[] inputBuffer = new char[ll];
isr.read(inputBuffer);
String readString = new String(inputBuffer);
Toast.makeText(getApplicationContext(), readString, Toast.LENGTH_LONG).show();
}
catch(IOException e){
// TODO: handle exception
}