I'm using Eclipse for a university project making an android app.
I'm having a problem with 1 thing:
I have created a class called TextFileHandler.
The idea is that the app instantiates TextFileHandler and uses the methods
to read and write the text files within the app with get methods simply
returning a string value and set methods writing new values to the text files.
When this class is instantiated the constructor creates a text file.
The methods are supposed to access the created text files and read and write them
but the problem is, once it creates the text files it can't seem to access them
and the app just crashes.
I have included the constructor and then directly after the method getMeds()
which just crashes every time. I'm not sure why it can't find the text files.
Any help would be appreciated.
constructor:
public TextFileHandler(Context ctx){
this.context = ctx;
//create the medicine text file
String medtext = "1#Med*2#Med*3#Med*4#Med*5#Med*";
try {
File file = new File("Medicine.txt");
//if the file doesn't already exist then create it
//this is to make sure the app saves state
if(!file.exists()){
BufferedWriter output = new BufferedWriter(new FileWriter(file));
output.write(medtext);
output.close();
}
} catch ( IOException e ) {
e.printStackTrace();
}
String remtext = "1a#000000*1b#000000*1c#000000*1d#000000*1e#000000*";
remtext += "2a#000000*2b#000000*2c#000000*2d#000000*2e#000000*";
remtext += "3a#000000*3b#000000*3c#000000*3d#000000*3e#000000*";
remtext += "4a#000000*4b#000000*4c#000000*4d#000000*4e#000000*";
remtext += "5a#000000*5b#000000*5c#000000*5d#000000*5e#000000*";
try {
File file = new File("Reminder.txt");
//if the file doesn't already exist then create it
//this is to make sure the app saves state
if(!file.exists()){
BufferedWriter output = new BufferedWriter(new FileWriter(file));
output.write(remtext);
output.close();
}
} catch ( IOException e ) {
e.printStackTrace();
}
}
get method:
public String getMeds() throws IOException{
FileInputStream in = openFileInput("Medicine.txt");
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String ret = sb.toString();
return ret;
}
Create your file either privately (readable only by your app) using ctx.openFileOutput("Medicine.txt", MODE_PRIVATE) or publicly using new File(Environment.getExternalStorageDirectory(), "Medicine.txt").
To read the private file, use Context.openFileInput(String name).
Related
I'm new to android studio and I have this textview which shows the data that is stored to my text file. If I click the button, it should read the data inside the text file, add integer and the sum should replace the existing data in the text file. However when I return to the activity which show's the textView with the new data in the text file, it does not change.
Here's the code for my textView
txt_stars = (TextView) findViewById(R.id.txtStars);
try {
FileInputStream fileInputStream = openFileInput("Stars.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star=bufferedReader.readLine()) != null){
stringBuffer.append(star);
}
txt_stars.setText(stringBuffer.toString());
}
catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And the code for the button
Integer stars, totalStars;
public void onClick(DialogInterface dialog, int whichButton) {
try {
FileInputStream fileInputStream = openFileInput("Stars.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star = bufferedReader.readLine()) != null) {
stringBuffer.append(star);
}
stars = Integer.parseInt(stringBuffer.toString());
totalStars = stars + 50;
//is this acceptable?
FileOutputStream fileOutputStream = openFileOutput("Stars.txt", MODE_PRIVATE);
fileOutputStream.write(totalStars.toString().getBytes());
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Intent nextForm = new Intent(".MainActivity");
startActivity(nextForm);
}
And also, where can I find the created text file in my phone so that I can assure that the text file is created? I'm using Android studio 1.5.1 and running the app to my phone.
I have this in my manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Is there anything I should do to locate and create the text file?
I have been stuck here for days. Please help me.
Thanks a lot!
This might be due to a FileNotFoundException when you'd read the file in the save method. When you try to update the file and write into it, you don't separate the try/catch methods so you might have an exception at the reading part which prevents to continue the script and to update the file. Maybe this was printing in the Logcat but you haven't take a look.
So I'd suggest you to check if the file already exists and to separate the reading/writing parts.
When you first read the file to display it in TextView, just check if it's created to avoid a background exception:
File f = new File(getFilesDir().toString() + "/stars.txt");
Log.v("", "Does the file exist? " + f.exists());
if (f.exists()) {
readFile();
}
You can see here where the file should be stored (in getFilesDir()). The path is choosen by default when you use openFileInput(String), and it's:
data/data/com.package.name/files/
You have to keep in mind that you actually don't create /files folder in your code and for example, I had to create it myself to work with the above method. (This can be only my device but you'd be aware this can prevent the file to be created.)
Now, there is no big changes in your reading method and this is how it looks:
private void readFile() {
try {
FileInputStream file = openFileInput("stars.txt");
InputStreamReader inRead = new InputStreamReader(file);
BufferedReader buffReader = new BufferedReader(inRead);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star = buffReader.readLine()) != null) {
stringBuffer.append(star);
}
inRead.close();
file.close();
txt_stars.setText(stringBuffer.toString());
} catch (Exception e) {
Log.e("ReadFile", e.toString());
}
}
Obviously, this method is called only if the previous check returns true. You have to do the same when the Button is clicked: check if it exists -> if yes, get the content, do your stuff (add, sum, etc) and write into it -> if not, just create it by writing into it.
Something as follows will work:
public void writeFile(View v) {
File f = new File(getFilesDir().toString() + "/stars.txt");
Log.v("", "Does it exist? " + f.exists());
String result = "";
if ( f.exists() ) {
try {
FileInputStream file = openFileInput("stars.txt");
InputStreamReader inRead = new InputStreamReader(file);
BufferedReader buffReader = new BufferedReader(inRead);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star=buffReader.readLine()) != null) {
stringBuffer.append(star);
}
result = stringBuffer.toString();
inRead.close();
file.close();
} catch (Exception e) {
Log.e("WriteFile", "--- Error on reading file: "+e.toString());
}
} else {
// get the user's star or whatever
result = editRating.getText().toString();
}
Log.v("WriteFile", "--- Read file returns: " + result);
stars = Integer.parseInt(result);
totalStars = stars + 50;
try {
FileOutputStream fileOut = openFileOutput("stars.txt", MODE_PRIVATE);
OutputStreamWriter outputWriter = new OutputStreamWriter(fileOut);
outputWriter.write(String.valueOf(totalStars));
outputWriter.close();
fileOut.close();
// display file saved message
Toast.makeText(getBaseContext(), "File saved", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(" WriteFile", e.toString());
}
}
At this point, when you returned to the previous activity, you should be able to see the changes.
However, in order to see the file in your storage, you unfortunately must to have a rooted device, else you'll see an empty folder. Then finally, you'd avoid to restart the Activity. You should finish the editing one, this will come back to the previous one, and you just have to call readFile() in onResume() instead of onCreate(). It will update the new content into the TextView.
Have you tried on updating textview before starting new Activity? Example:
txt_start.setText(""+totalStars);
So, here's the problem: I'm working on a Java program that reads from a .csv file, and constructs objects out of it. I'm using InputStream, InputStreamReader, and BufferedReader to read the file. The IDE I'm using is NetBeans and the file being read is in the src directory. A quick note, for your convenience, I hardcoded the filename, so that you would understand how it's actually being read. In my actual program, the filename is being passed in as a parameter of the method. Anyways, it seems to work fine in the IDE. But when I create a JAR, it doesn't do what I want it to do.
public void readFile(filename) throws IOException, FileNotFoundException {
is = getClass().getResourceAsStream("file.csv");
isr = new InputStreamReader(is);
//fr = new FileReader(filename);
br = new BufferedReader(isr);
String info;
while ((info = br.readLine()) != null)
{
String[] tokens = info.split(",");
Object object = new Object();
object.setProperty(tokens[0]);
object.setAnotherProperty(tokens[1]);
object.setSomeOtherProperty(tokens[2]);
}
}
catch (FileNotFoundException f)
{
f.getMessage();
}
catch (IOException ioe)
{
ioe.getMessage();
}
catch (ArrayIndexOutOfBoundsException oob)
{
//;
}
catch (NullPointerException npe)
{
//;
}
finally
{
br.close();
isr.close();
is.close();
}
My method to update the file looks like this(once again, the filename has been hardcoded so you could better understand what's going on):
public void updateRoom(String filename, String property1, string property2, string property3) throws FileNotFoundException
{
for (Objects o : objects)
{
if (o.getProperty().equals(property1))
{
o.setProperty(property1);
o.setAnotherProperty(property2);
o.setSomeOtherProperty(property3);
}
}
File file = new File("file.csv");
PrintWriter pr = new PrintWriter(file);
for (Object o : objects)
{
pr.println(o.getProperty() + "," +
o.getAnotherProperty() + "," +
o.getSomeOtherProperty())
}
pr.close();
}
The problem is that the .JAR reads the file when I run it, but instead of writing to the SAME file, it simply creates a new one and writes to that one. It's a problem because every time I run the program again, the properties and values remain unchanged. It's NOT reading from the newly-created file. It's still reading from the original file, but it's writing to a new file.
I want to READ AND WRITE to the same file. That way, if I close the program and run it again, it will have the new properties/values already loaded in.
I know previous questions LIKE this one have been asked, but this question has to do with the specifics of the code that I have written. I am trying to update a single line of code on a file that will be permanently updated even when the program terminates so that the data can be brought up again. The method that I am writing currently looks like this (no compile errors found with eclipse)
public static void editLine(String fileName, String name, int element,
String content) throws IOException {
try {
// Open the file specified in the fileName parameter.
FileInputStream fStream = new FileInputStream(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(
fStream));
String strLine;
StringBuilder fileContent = new StringBuilder();
// Read line by line.
while ((strLine = br.readLine()) != null) {
String tokens[] = strLine.split(" ");
if (tokens.length > 0) {
if (tokens[0].equals(name)) {
tokens[element] = content;
String newLine = tokens[0] + " " + tokens[1] + " "
+ tokens[2];
fileContent.append(newLine);
fileContent.append("\n");
} else {
fileContent.append(strLine);
fileContent.append("\n");
}
}
/*
* File Content now has updated content to be used to override
* content of the text file
*/
FileWriter fStreamWrite = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fStreamWrite);
out.write(fileContent.toString());
out.close();
// Close InputStream.
br.close();
}
} catch (IOException e) {
System.out.println("COULD NOT UPDATE FILE!");
System.exit(0);
}
}
If you could look at the code and let me know what you would suggest, that would be wonderful, because currently I am only getting my catch message.
Okay. First off the bat, StringBuilder fileContent = new StringBuilder(); is bad practice as this file could well be larger than the user's available memory. You should not keep much of the file in memory at all. Do this by reading into a buffer, processing the buffer (adjusting it if necessary), and writing the buffer to a new file. When done, delete the old file and rename the secondary to the old one's name. Hope this helps.
I have a .txt file in ExternalStorageDirectory() in Android. This file contains 10 sentence line by line. I want to read each sentence one by one. And then show it on EditText when every button click. I found only all file reading codes. I don't want this. How can I do that? Here is my little code:
enter cod private String Load() {
String result = null;;
String FILE_NAME = "counter.txt";
//if (isExternalStorageAvailable() && isExternalStorageReadOnly()) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "Records";
File file = new File(baseDir, FILE_NAME);
String line = "";
StringBuilder text = new StringBuilder();
try {
FileReader fReader = new FileReader(file);
BufferedReader bReader = new BufferedReader(fReader);
while( (line = bReader.readLine()) != null ){
text.append(line+"\n");
}
result = String.valueOf(text);
} catch (IOException e) {
e.printStackTrace();
}
//}
return result;
}
All Load() does is reads the file and returns it as a String. From here, you have a few options.
1).
Convert the result to an array of Strings using String.split('\n'), and grab the next value when you click the button. Here's a quick example:
int counter = 0;
String file = Load();
String[] lines = file.split("\n");
button.onClicked() {
editText.setText(lines[counter++]);
}
2).
Declare the buffered reader as a class member, so you can call readLine() inside the button's onClicked() method. This way, it will only read one line of the file when someone clicks the button, instead of reading the whole file in Load().
I am using the below code for reading my file and it is working fine, but now I want to add new text to that file. Please help me
private void loadingDictionary() {
// TODO Auto-generated method stub
AssetManager mgr;
try{
mgr = getAssets();
InputStream is = mgr.open("dictinary.txt");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder stringBuilder = new StringBuilder();
String ls = ",";
while(( line = br.readLine() ) != null){
stringBuilder.append( line );
stringBuilder.append( ls );
}
dictinaryLines = stringBuilder.toString();
dictLinesArray = dictinaryLines.split(ls);
}
catch(IOException e1){
}
}
I want to append the new text to the already existing data.
Please help me.
As far as I know you can not write to the assets folder. You should copy the data from your assets folder to the private of your application or even to the external storage, depending on how confident your data is.
See How to write files to assets folder or raw folder in android?
You can't. How ever you can append a string called by res/values/strings.xml. If you were doing a theme I would have suggested to declare a string in res/values.strings.xml, and append it, then have whatever app you wanted to change whatever text to read from strngs.xml.