I am new to android and currently trying to save a few files in a little "play-around" application I am making to learn, however the files only seem to persist until the application is shut down. When I run:
file.exists()
file.isFile()
or any similar methods they always return false when the application is restarted.
This is the method I found online to save files:
public void writeToFile(String data, String filePath, Context context){
File file = new File(context.getFilesDir(), filePath);
if(!file.exists()){
try{
file.createNewFile();
}catch(IOException e) {
e.printStackTrace();
Log.e("Exception", "File couldn't be created");
}
}
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(filePath, Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
I have been googling a lot trying to find a solution but none of them worked. It seems to work when the application is running since I can write and read the files, however at a restart of the application, it cannot find the files. (file.exists() returns false)
I just spend an hour tracking down this same bug and it turned out it was because the "Clear User Data" flag was set under "Deployment" in the project properties. I'm using NVIDIA CodeWorks for Android with Visual Studio 2017.
I assume that you are attempting to write to internal storage here? If not and you wish to access external storage, I would suggest having a look through the guidance on Android.com below.
https://developer.android.com/guide/topics/data/data-storage.html#filesInternal
If this is internal storage that you are trying to write to, then you need to make sure that you are passing the correct context to the method. For example, if you were running from your MainActivity class and the method was contained within that class, your call would be something along the lines of:
writeToFile("Some data", "aFile.txt", MainActivity.this)
Related
I programmed a little game that also has a highscore being displayed when the game is over.
The highscore is saved into a integer variable simply called highscore.
Now I am trying to safe the highscore into a file to avoid it being reset everytime you close the app.
My approach was using a FileWriter as you can see below. The game is still running smoothly and everything is fine I don't get any errors etc. but it does not safe anything into the file.
I just don't understand why.
Thankful for any help.
private void saveHighscore() {
File highscoreFile = new File("C:\\Users\\FuadM\\Desktop\\Mueckenfang\\Highscore.txt");
try (FileWriter highscoreWriter = new FileWriter(highscoreFile)) {
if (!highscoreFile.exists()) {
highscoreFile.createNewFile();
}
highscoreWriter.write("" + highscore);
} catch (IOException e) {
e.printStackTrace();
}
}
EDIT: I just checked and I am getting this message in the terminal:
W/System.err: java.io.FileNotFoundException:
C:\Users\FuadM\Desktop\Mueckenfang\Highscore.txt: open failed: EROFS
(Read- only file system)
Android doesn't have a C: drive, or a desktop, or a Mueckenfang directory. I'm not quite sure what your thought process was, but your phone is certainly not going to be capable of writing files on your PC's desktop.
You can write to files on Android, but that's not what you should be doing here. Android apps ship with SQLite (a simple database system) built in, and that's where a game should be storing a high score. I think your next step should be to search the web for a tutorial on how to do SQLite from Android.
I have this piece of code for saving accelerometer data in a file , but i cant find that file in my internal storage.
String file_name="hello_file";
try {
FileOutputStream fileOutputStream=openFileOutput(file_name, Context.MODE_PRIVATE);
fileOutputStream.write(message.getBytes());
fileOutputStream.close();
Toast.makeText(getApplicationContext(),"saved",Toast.LENGTH_LONG).show();
acceleration.setText("");
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
getFilesDir() gives the location of where openFileOutput() writes files.
That said, those files are not accessible by users. They could access them actually but if they had a rooted device at hand.
Here's a tutorial regarding Internal and External storage.
I don't know how much you know about Android storage but just to clarify External isn't really external in the sense of an external hard-drive. It's external as on a different partition from the one holding the OS. It is still 'internal' in the sense that it's not on an sdcard. But still even if you don't have an SD card installed, Android could name your external(non-system) storage sdcard/ .... So yeah, lots of confusion initially.
I need to write a custom batch File renamer. I've got the bulk of it done except I can't figure out how to check if a file is already open. I'm just using the java.io.File package and there is a canWrite() method but that doesn't seem to test if the file is in use by another program. Any ideas on how I can make this work?
Using the Apache Commons IO library...
boolean isFileUnlocked = false;
try {
org.apache.commons.io.FileUtils.touch(yourFile);
isFileUnlocked = true;
} catch (IOException e) {
isFileUnlocked = false;
}
if(isFileUnlocked){
// Do stuff you need to do with a file that is NOT locked.
} else {
// Do stuff you need to do with a file that IS locked
}
(The Q&A is about how to deal with Windows "open file" locks ... not how implement this kind of locking portably.)
This whole issue is fraught with portability issues and race conditions:
You could try to use FileLock, but it is not necessarily supported for your OS and/or filesystem.
It appears that on Windows you may be unable to use FileLock if another application has opened the file in a particular way.
Even if you did manage to use FileLock or something else, you've still got the problem that something may come in and open the file between you testing the file and doing the rename.
A simpler though non-portable solution is to just try the rename (or whatever it is you are trying to do) and diagnose the return value and / or any Java exceptions that arise due to opened files.
Notes:
If you use the Files API instead of the File API you will get more information in the event of a failure.
On systems (e.g. Linux) where you are allowed to rename a locked or open file, you won't get any failure result or exceptions. The operation will just succeed. However, on such systems you generally don't need to worry if a file is already open, since the OS doesn't lock files on open.
// TO CHECK WHETHER A FILE IS OPENED
// OR NOT (not for .txt files)
// the file we want to check
String fileName = "C:\\Text.xlsx";
File file = new File(fileName);
// try to rename the file with the same name
File sameFileName = new File(fileName);
if(file.renameTo(sameFileName)){
// if the file is renamed
System.out.println("file is closed");
}else{
// if the file didnt accept the renaming operation
System.out.println("file is opened");
}
On Windows I found the answer https://stackoverflow.com/a/13706972/3014879 using
fileIsLocked = !file.renameTo(file)
most useful, as it avoids false positives when processing write protected (or readonly) files.
org.apache.commons.io.FileUtils.touch(yourFile) doesn't check if your file is open or not. Instead, it changes the timestamp of the file to the current time.
I used IOException and it works just fine:
try
{
String filePath = "C:\sheet.xlsx";
FileWriter fw = new FileWriter(filePath );
}
catch (IOException e)
{
System.out.println("File is open");
}
I don't think you'll ever get a definitive solution for this, the operating system isn't necessarily going to tell you if the file is open or not.
You might get some mileage out of java.nio.channels.FileLock, although the javadoc is loaded with caveats.
Hi I really hope this helps.
I tried all the options before and none really work on Windows. The only think that helped me accomplish this was trying to move the file. Event to the same place under an ATOMIC_MOVE. If the file is being written by another program or Java thread, this definitely will produce an Exception.
try{
Files.move(Paths.get(currentFile.getPath()),
Paths.get(currentFile.getPath()), StandardCopyOption.ATOMIC_MOVE);
// DO YOUR STUFF HERE SINCE IT IS NOT BEING WRITTEN BY ANOTHER PROGRAM
} catch (Exception e){
// DO NOT WRITE THEN SINCE THE FILE IS BEING WRITTEN BY ANOTHER PROGRAM
}
If file is in use FileOutputStream fileOutputStream = new FileOutputStream(file); returns java.io.FileNotFoundException with 'The process cannot access the file because it is being used by another process' in the exception message.
I am trying to add a way to save data to the android phone for my app. In the surfaceOnDestroyed I have added the following code.
try {
outputStream = getContext().openFileOutput("data.txt", Context.MODE_PRIVATE);
outputStream.write(current.getBytes());
outputStream.close();
System.out.println(current + " saved");
} catch(Exception e) {
e.printStackTrace();
}
Current is a string variable that I call earlier in my code that I print out here to show what it is when I am writing to the file. Each time I get that the variable is 2.
The data.txt file contains one line with a "0" initially placed in the file because the program reads from the file when the application is started.
When I check the data file after I destroy the object, the 0 is still in the file and has not changed to the 2.
I'm not sure what other information might be needed to solve this issue but I can not figure it out. Help much appreciated.
I am attempting to write a JApplet that uses information in a text file to load and save data from. I have successfully got the applet to load the information, but the saving appears to be having issues. I have included the code to save below. the file name I am using is the same as I use to write to. The file must be included in the JAR when I run because the applet initializes properly. Is there any reason why the writing sin't working properly? i have resorted to calling this method from both the stop() and destroy() methods.
As a note, the load and saving both work perfectly when run from eclipse, but when in a JAR only the loading works, but nothing saves so I can't change the load data.
Ideally, I want this saveLocations() method to be called whenever the page is closed or refreshed.
NOTE: mOUtputStream is indeed a PrintWriter (it used to be an OutputStream, I guess I should change the name)
Thanks so much in advance for the help.
private void saveLocations() throws IOException {
//JOptionPane.showMessageDialog(null, "Alert", "Saving", JOptionPane.INFORMATION_MESSAGE);
// System.out.println("saving!");
try {
mOutputStream = new PrintWriter(new File(getClass().getResource("/listings/saveData.txt").toURI()));
}
catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(locations.size());
for (Location l : locations) {
System.out.println("r: " + l.getRawListing());
mOutputStream.print(l.getRawListing()+ "\n");
}
if (mOutputStream != null)
mOutputStream.close();
}
You can't write to a file inside a JAR file -- period. Don't even try. If you need to write to a file, then that file has to be outside the JAR. For an applet, that would require it to be signed, and to ask the user for specific permission to do so.
In the applet case, I'm not sure what copy of the JAR file you're hoping will be written to: the copy in the browser cache, or the copy on the server? Either way, it's not going to happen.