First of all, I would like you to say that I am quite new here and I'm also a beginner in Android Studio and Java.
My problem/question is:
I have an App in Android Studio which should write a string to a text file at a specific point and also should read the same file on App startup.
Writing to the file is working but not reading. When I create a text file manually, and insert it manually to the folder it reads the string.
I already added permissions and try to find my error with LogCat but I have no clue at the moment what could be wrong.
Variables:
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myApp");
My reading function:
String myData = "";
try {
FileReader fileIn = new FileReader(dir + "/data.txt");
Scanner input = new Scanner(fileIn);
while (input.hasNextLine()) {
String line = input.nextLine();
myData = myData + line;
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
My writing function:
try {
File file = new File(dir, "data.txt");
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("answer42");
pw.flush();
pw.close();
f.close();
} catch (Exception ex) {
ex.printStackTrace();
}
Related
I’ve a problem with understanding paths in Android. I’m trying to check if file exists. It works fine in pure Java but fails in Android code and I’m giving the path in the same way (it’s just a file name). I know the file exists (in Android) because I’ve checked it by reading from it before calling to exists() method of File class. I can read the file with no problem but existence check returns false. So my question is: what is the difference between ‘normal’ and ‘android’ Java when it comes to paths?
This problem seems similar to ‘why file.exists() returns false?’ but I’ve done some reading (a lot of it) and didn’t find an answer (to both – how to check if file exists in Android and what’s the difference between paths in pure Java and Java in Android).
Below I’m pasting the code illustrating the case.
This doesn't work in Android:
//--------------------------BUTTONS ACTIONS-----------------------------------------------------
public void onSaveButtonClick(View view){
msg = textInput.getText().toString();
try {
FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);
fos.write(msg.getBytes());
fos.close();
Toast.makeText(getApplicationContext(), "Zapiasano!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onLoadButtonClick(View view){
loadedMsg = "";
String tmp;
try {
FileInputStream fis = openFileInput(fileName);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuffer stringBuffer = new StringBuffer();
while ((tmp=bufferedReader.readLine()) != null){
loadedMsg += tmp + "\n";
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
textDisplay.setText(loadedMsg);
//----------------------FILE CHECK---------------------------------------------
File f = new File(fileName);
if(f.exists()){
textDisplay.setText("File exsists");
} else{
textDisplay.setText("File doesn't exsists");
}
}
And this works in pure Java:
public static void main(String[] args) {
String fileName = "test.file";
String str = "hello kitty!";
String loaded = "this should not load";
//-----------------SAVE------------------------------------------------
try {
FileOutputStream fos;
fos = new FileOutputStream(fileName);
fos.write(str.getBytes());
fos.close();
System.out.println("saved");
} catch (FileNotFoundException ex) {
Logger.getLogger(FileExists.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(FileExists.class.getName()).log(Level.SEVERE, null, ex);
}
//------------------LOAD -----------------------------------------------
try {
FileInputStream fis = new FileInputStream(fileName);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
loaded = bufferedReader.readLine();
isr.close();
fis.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(FileExists.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(FileExists.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(loaded);
//----------------------FILE CHECK---------------------------------------------
File file = new File(fileName);
if(file.exists()){
System.out.println("file exsists");
}
}
OUTPUT:
saved
hello kitty!
file exsists
So my question is: what is the difference between ‘normal’ and ‘android’ Java when it comes to paths?
Other Java environments assume a certain current working directory. For all intents and purposes, Android does not.
Your Android code assumes that the following three things are related:
FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);
FileInputStream fis = openFileInput(fileName);
File f = new File(fileName);
The first two are related. The third is meaningless. The equivalent line would be:
File f = new File(getFilesDir(), fileName);
In Android, you always determine filesystem paths using framework-supplied methods to give you the base directories to work from (getFilesDir(), getExternalFilesDir(), methods on Environment, etc.).
Both the implementation of FileOutputStream(filename) save the file at the location given by the filename. So they kind of assume that its actually the absolute path to file.
The difference is the 'reference' they use to get to that path.
Java on your system sees that path with respect to the source location,
so you use the FileOutputStream(filename) to save file at //filename and then use File(filename) to get that file from /<reference path>/filename and you always find the file therere.
Android's FileOutputStream(filename) sees that location with respect to the files/ directory inside your package directory. While its implementation of File(pathname) see the path with respect to the root directory.
So, in android, when you write using FileOutputStream(filename), you are writing to a file /<path to your package directory>/files/filename, but when you use File(), you actually try to access a file at the root ie /filename, which, do not really exists.
Instead try:
....
File f = new File (YourActivity.this.getFilesDir().getAbsolutePath() + filename);
...
I want to read a file from the user's desktop, and then write a new file to the desktop. Below is the code to do this on my own computer, but I'm not sure how to do it for any user.
I found this previously-asked question, but I'm not sure how to implement such a method in Java. Would I possibly use the System.getProperty() method?
Any help or advice is appreciated. Thanks!
public static String [] read()
{
ArrayList<String> fileArrList = new ArrayList<>();
Scanner scan = new Scanner(System.in);
System.out.print("File name > ");
String fileName = scan.nextLine();
try
{
Scanner file = new Scanner(new File("C:\\Users\\pez\\Desktop\\" + fileName));
while (file.hasNextLine())
{
String line = file.nextLine();
fileArrList.add(line);
}
file.close();
String [] fileArr = new String[fileArrList.size()];
fileArr = fileArrList.toArray(fileArr);
return fileArr;
}
catch (FileNotFoundException fnfe)
{
System.out.println("File not found");
}
return null;
}
public static void writeNewFile(ArrayList outputArr)
{
try
{
FileOutputStream fos = new FileOutputStream("C:\\Users\\pez\\Desktop\\output.txt", false);
PrintWriter pw = new PrintWriter(fos);
for (Object i : outputArr)
{
pw.println(i);
}
pw.close();
}
catch (FileNotFoundException fnfe)
{
}
}
You can use the system property user.home:
File desktop = new File(System.getProperty("user.home"), "/Desktop");
Scanner file = new Scanner(new File(desktop, fileName));
I assume you know you are limited to windows environments this way.
I'll give you simple examples that you can implement in your project.
To get windows username you can get the property user.name:
System.getProperty("user.name");
To write on a file you can use this simple code:
PrintWriter writer = new PrintWriter("filename.txt", "UTF-8");
writer.println("Some text");
writer.println("Some other text");
writer.close();
To read a text file you can use this:
BufferedReader br = new BufferedReader(new FileReader("/path/to/filename.txt"));
String textLine = null;
while ((textLine = br.readLine()) != null) {
System.out.println(textLine);
}
You can implement all this code in your project easily.
I hope you find this usefull, sorry for my english.
I am trying to Edit a existing file which is in my R.raw folder
i am able to read the file
but when i run the write function it is not working .
public void tofile(View v){
BufferedWriter bw=null;
FileWriter fw =null;
try {
String path = ("/Page2/res/raw/text.txt");
File file = new File(path);
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
bw.write("hello");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
i even tried
fw = new FileWriter(file,true);
if i add toast between even line it seems to get stuck at
fw = new FileWriter(fw);
You can't able to Write
As #CommonsWare said you can't write on resources but you could use internal storage using openFileOutput and openFileInput and BufferedReaders and BufferedWriters. You can check it here
from the answer of #rodkarom in the following link
Write to a Text File Resource in Android
and #Andro Selva says same thing in the following link
How to write a file in Android to the raw folder?
you can able to read the content from the textfile which is present in the res/raw folder dude
read the file from res folder
public String readStringFromResource(Context ctx, int resourceID) {
StringBuilder contents = new StringBuilder();
String sep = System.getProperty("line.separator");
try {
InputStream is = ctx.getResources().openRawResource(R.raw.trails);
BufferedReader input = new BufferedReader(new InputStreamReader(is), 1024*8);
try {
String line = null;
while (( line = input.readLine()) != null){
contents.append(line);
contents.append(sep);
}
}
finally {
input.close();
}
}
catch (FileNotFoundException ex) {
Log.e(TAG, "Couldn't find the file " + resourceID + " " + ex);
return null;
}
catch (IOException ex){
Log.e(TAG, "Error reading file " + resourceID + " " + ex);
return null;
}
return contents.toString();
}
check it and inform
Right, I've been trying to find a solution to this for a good while, but it's just not working for some reason.
In short, what I want to do is save every input String the user inputs into a file. Every time the activity is created again, I want to re-input these strings into a new instance of an object.
This code is what I use to create the file and read info from it, used in the onCreate() method of activity
try {
String brain = "brain";
File file = new File(this.getFilesDir(), brain);
if (!file.exists()) {
file.createNewFile();
}
BufferedReader in = new BufferedReader(new FileReader(file));
String s; // This feeds the object MegaAndroid with the strings, sequentially
while ((s = in.readLine()) != null) {
MegaAndroid.add(s);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
After that, every time the user inputs some text, the strings are saved onto the file:
try {
String brain = "brain";
File file = new File(this.getFilesDir(), brain);
if (!file.exists()) {
file.createNewFile();
}
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(message); // message is a string that holds the user input
out.close();
} catch (IOException e) {
e.printStackTrace();
}
For some reason, however, every time the application is killed, the data is lost.
What am I doing wrong?
EDIT: Also, if I were to access this file from another class, how can I?
As we discussed in the commend section the chief problem with the code is that your execution of FileWriter occurred prior to your FileReader operation while truncating the file. For you to maintain the file contents you want to set the write operation to an append:
BufferedWriter out = new BufferedWriter(new FileWriter(file,true));
out.write(message);
out.newLine();
out.close();
However, if every entry on the EditText is received then shipped into the file you'll just be writing data byte after byte beside it. It is easy to get contents similar to
This is line #1This is line #2
Instead of the desired
This is line #1
This is line #2
which would be corrected by having the BufferedWriter pass a newline after each write to the file.
This is what I do for file reading.
try{
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/whereyouwantfile");
dir.mkdirs();
Log.d(TAG,"path: "+dir.getAbsolutePath());
File file = new File(dir, "VERSION_FILENAME");
FileInputStream f = new FileInputStream(file);
//FileInputStream fis = context.openFileInput(VERSION_FILENAME);
BufferedReader reader = new BufferedReader(new InputStreamReader(f));
String line = reader.readLine();
Log.d(TAG,"first line versions: "+line);
while(line != null){
Log.d(TAG,"line: "+line);
//Process line how you need
line = reader.readLine();
}
reader.close();
f.close();
}
catch(Exception e){
Log.e(TAG,"Error retrieving cached data.");
}
And the following for writing
try{
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/whereyouwantfile");
dir.mkdirs();
File file = new File(dir, "CONTENT_FILENAME");
FileOutputStream f = new FileOutputStream(file);
//FileOutputStream fos = context.openFileOutput(CONTENT_FILENAME, Context.MODE_PRIVATE);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(f));
Set<String> keys = Content.keySet();
for(String key : keys){
String data = Content.get(key);
Log.d(TAG,"Writing: "+key+","+data);
writer.write(data);
writer.newLine();
}
writer.close();
f.close();
}
catch(Exception e){
e.printStackTrace();
Log.e(TAG,"Error writing cached data.");
}
You can use the private mode if you don't want the rest of the world to be able to see your files, but it is often useful to see them when debugging.
I'm trying to open a file in android like this :
try
{
FileInputStream fIn = context.openFileInput(FILE);
DataInputStream in = new DataInputStream(fIn);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
if(in!=null)
in.close();
}
catch(Exception e)
{ }
, but in case the file does not exists a file not found exception is thrown . I'd like to know how could I test if the file exists before attempting to open it.
I think the best way to know if a file exists, without actually trying to open it, is as follows:
File file = getContext().getFileStreamPath(FILE_NAME);
if(file.exists()) ...
The documentation says Context.openFileInput either returns an inputStream (file found) or throws a FileNotFoundException (not found)
http://developer.android.com/reference/android/content/Context.html#openFileInput(java.lang.String)
So it looks like the exception is your "test".
You could also try using standard
java.io.File file = new java.io.File(PATHTOYOURCONTEXT , FILE);
if (file.exists()) {
FileInputStream fIn = new FileInputStream(file);
}
But that is not recommended. Context.openFileInput() and Context.openFileOutput() make sure you stay in your applications storage context on the device, and that all of your files get
deleted when your app gets uninstalled.
With the standard java.io.File this is the function I have created, and works correctly:
private static final String APP_SD_PATH = "/Android/data/com.pkg.myPackage";
...
public boolean fileExistsInSD(String sFileName){
String sFolder = Environment.getExternalStorageDirectory().toString() +
APP_SD_PATH + "/Myfolder";
String sFile=sFolder+"/"+sFileName;
java.io.File file = new java.io.File(sFile);
return file.exists();
}
why dont you just catch the FileNotFound exception and take that as the file not being present.
If you want to ensure a file exists (i.e. if it doesn't exist create a new one, if it does then don't erase it) then use File.createNewFile:
https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()
e.g.
{
String pathName = <file path name>
File file = new File (pathName);
Uri pathURI = Uri.fromFile (file);
boolean created;
String mIOException = "";
String mSecException = "";
try
{
created = file.createNewFile();
if (created)
{
ctxt.sendBroadcast (new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, pathURI));
}
}
catch (IOException ioex)
{
mIOException = ioex.getMessage();
}
catch (SecurityException sex)
{
mSecException = sex.getMessage();
}
}
If you want to open a file in any case (i.e. if it doesn't exist create a new one, if it does append to the old one) you can use this, no testing necessary:
public static void write_custom_log(String message){
File root = Environment.getExternalStorageDirectory();
try{
BufferedWriter fw = new BufferedWriter(new FileWriter(new File("/mnt/sdcard/tjb_tests/tjb_log_file.txt"),true));
if (root.canWrite()){
fw.write(message);
fw.close();
}
} catch (IOException e) {
Log.e("One", "Could not write file " + e.getMessage());
}
}
My suggestion is to check length of the file. if file.length() returns 0 that means file doesn't exist.