I have Server-Client messenger - not important - and I have a settings file to store the settings, but for some reason when I run the code, the settings file clears.
Here is the code that makes the settings file and directory:
boolean exists = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server").mkdir();
File directory = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server");
File settingsFile = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server\\settings.txt");
if(exists){
try {
directory.createNewFile();
System.out.println("Created");
} catch (IOException e) {
e.printStackTrace();
}
}
if(!settingsFile.exists()){
try {
settingsFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Created Settings.txt");
System.out.println(settingsFile.getAbsolutePath());
}
And this is the code that reads and writes to the file:
try {
FileReader fileReader = new FileReader(settingsFile);
FileWriter fileWriter = new FileWriter(settingsFile);
BufferedReader bf = new BufferedReader(fileReader);
BufferedWriter bw = new BufferedWriter(fileWriter);
}catch(IOException b){
b.printStackTrace();
}
ArrayList<String> settingList = new ArrayList<String>();
for (int i = 0; i < 6; i++) {
try {
settingList.add(bf.readLine());
} catch (IOException ex) {
ex.printStackTrace();
}
}
if(!settingList.get(0).equals("alwaysOnTop=true")&&!settingList.get(0).equals("alwaysOnTop=false")){
try {
bw.write("alwaysOnTop=false");
} catch (IOException ex) {
ex.printStackTrace();
}
}
The FileWriter constructor can take a boolean argument ( FileWriter(File file, boolean append) ), which if true makes the FileWriter append to the file instead of overwriting it every time. Like this:
FileWriter fileWriter = new FileWriter(settingsFile, true);
The answer from #JustusG is correct.
Still, I would not recommend using .txt files to keep the settings of your app.
Since they are hard to maintain, you may have duplicate settings (because of appending...) and so on.
I would recommend using .properties files. At the end of the day they do the same thing, it's just that .properties files have classes to read and to write your settings/properties.
Here is an example:
Properties prop = new Properties();
File propFile = new File("path/to/app.properties");
InputStream in = new FileInputStream(propFile); // Open the prop file
prop.load(in); // Load it in the Properties object
prop.setProperty("setting1", "value1"); // Setting a new setting to what you need OR setting an old setting to a new value.
String value2 = prop.getProperty("setting2"); // Reading a property
//And at the end, writing the properties that you changed (without duplicates)
prop.store(new FileOutputStream("xyz.properties"), null);
Related
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();
}
I am trying to make filewriter append instead of overwrite by using FileWriter("file.txt",true) but it is not working , also another problem (not sure if realted) is that I can't use File file1 = new File("a.txt") to create a file so I am using formatter. Note I am a beginner so please elaborate the mistakes I did if possible.
public static void newPlayer(){
String name = JOptionPane.showInputDialog("Write yourn name ","new player");
System.out.println(name +" " +points);
try {
Formatter file1 = new Formatter(name+".txt");
File file2 = new File(name+".txt");
fw = new FileWriter(file2,true);
String s = Integer.toString(points);
fw.write(s);
fw.close();
file1.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(Exception e){
System.out.println(e);
}
}
Remove the two lines regarding file1, it's not being used anyways.
Using the Formatter is opening the file with append=false, which is interfering with the settings from FileWriter (same file descriptor being used under the hood? OS dependent?).
...
try {
File file2 = new File(name+".txt");
FileWriter fw = new FileWriter(file2,true);
String s = Integer.toString(points);
fw.write(s);
// a line feed would make the file more readable
fw.close();
} catch (...
I removed file1 lines with the formatter and it works although before I tried it but it wasn't creating a file. if you have similar problem and the file isn't created try file.createnewfile();
try {
//Formatter file1 = new Formatter(name+".txt");
File file2 = new File(name+".txt");
// file2.createNewFile();
fw = new FileWriter(file2,true);
String s = Integer.toString(points);
fw.write(s);
fw.close();
//file1.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(Exception e){
System.out.println(e);
}
I'm using this to write to a text file. Works fine while program is open but when I close and reopen and start saving again it completely over writes the previous numbers.
private void writeNumbers(ArrayList<String> nums)
{
try
{
PrintStream oFile = new PrintStream("lottoNumbers.txt");
oFile.print(nums);
oFile.close();
}
catch(IOException ioe)
{
System.out.println("I/O Error" + ioe);
}
}
Are you reading in this text file upon starting the program? If the file you are writing to already exists, it always will overwrite it. If you want it to add to the file, you need to read it in upon starting the program, save that data somewhere, then write the OLD data + the NEW data to the file.
Although there might be an easier way of doing it, this is how i have done it in the past.
write an if statement to check if the file exists, if it exists you can use "file.append" else create a new one.
public class WriteToFileExample {
public static void main(String[] args) {
try {
String content = "This is the content to write into file";
File file = new File("/users/mkyong/filename.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
you can try this append mode
try {
Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
or
FileUtils.writeStringToFile(file, "String to append", true);
I have few text files. Each text file contains some path and/or the reference of some other file.
File1
#file#>D:/FilePath/File2.txt
Mod1>/home/admin1/mod1
Mod2>/home/admin1/mod2
File2
Mod3>/home/admin1/mod3
Mod4>/home/admin1/mod4
All I want is, copy all the paths Mod1, Mod2, Mod3, Mod4 in another text file by supplying only File1.txt as input to my java program.
What I have done till now?
public void readTextFile(String fileName){
try {
br = new BufferedReader(new FileReader(new File(fileName)));
String line = br.readLine();
while(line!=null){
if(line.startsWith("#file#>")){
String string[] = line.split(">");
readTextFile(string[1]);
}
else if(line.contains(">")){
String string[] = line.split(">");
svnLinks.put(string[0], string[1]);
}
line=br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Currently my code reads the contents of File2.txt only, control does not come back to File1.txt.
Please ask if more inputs are required.
First of all you are jumping to another file without closing the current reader and when you come back you lose the cursor. Read one file first and then write all its contents that match to another file. Close the current reader (Don't close the writer) and then open the next file to read and so on.
Seems pretty simple. You need to write your file once your svnLinks Map is populated, assuming your present code works (haven't seen anything too weird in it).
So, once the Map is populated, you could use something along the lines of:
File newFile = new File("myPath/myNewFile.txt");
// TODO check file can be written
// TODO check file exists or create
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream(newFile);
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
for (String key: svnLinks.keySet()) {
bw.write(key.concat(" my separator ").concat(svnLinks.get(key)).concat("myNewLine"));
}
}
catch (Throwable t) {
// TODO handle more gracefully
t.printStackTrace();
if (bw != null) {
try {
bw.close();
}
catch (Throwable t) {
t.printStackTrace();
}
}
Here is an non-recursive implementation of your method :
public static void readTextFile(String fileName) throws IOException {
LinkedList<String> list = new LinkedList<String>();
list.add(fileName);
while (!list.isEmpty()) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File(list.pop())));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("#file#>")) {
String string[] = line.split(">");
list.add(string[1]);
} else if (line.contains(">")) {
String string[] = line.split(">");
svnLinks.put(string[0], string[1]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
br.close();
}
}
}
Just used a LinkedList to maintain the order. I suggest you to add some counter if you to limit the reading of files to a certain number(depth). eg:
while (!list.isEmpty() && readCount < 10 )
This will eliminate the chance of running the code to infinity(in case of circular reference).
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.