-1

I want to increment the count every time my program runs. I tried running below code but it keeps on printing 1 every time i run the program. Also anything special i need to do to increase the date.

public class CounterTest {
    int count = 0;
    public static void main(String[] args) {
        CounterTest test1 = new CounterTest();
        test1.doMethod();
    }
    public void doMethod() {
        count++;
        System.out.println(count);
    }
}
Sam1977
  • 15
  • 4
  • 5
    If you want it to save between runs you would have to do something like load and store the data to a file or database. – sleepToken Sep 29 '20 at 00:57
  • Let's say i am storing the values in database but how i can retrieve the values from database and increase the values for the next program run? Is there a code snippet somewhere i can refer? – Sam1977 Sep 29 '20 at 01:07
  • 1
    Saving to a database varies depending on which database library you use, try looking up some examples. Saving to file might suit your needs better: https://stackoverflow.com/questions/1053467/how-do-i-save-a-string-to-a-text-file-using-java and you can read from the file like so: https://stackoverflow.com/questions/326390/how-do-i-create-a-java-string-from-the-contents-of-a-file – sorifiend Sep 29 '20 at 02:11

3 Answers3

2

You could simply create a properties file for your application to keep track of such things and application configuration details. This of course would be a simple text file containing property names (keys) and their respective values.

Two small methods can get you going:

The setProperty() Method:

With is method you can create a properties file and apply whatever property names and values you like. If the file doesn't already exist then it is automatically created at the file path specified:

public static boolean setProperty(String propertiesFilePath,
                                  String propertyName, String value) {
    
    java.util.Properties prop = new java.util.Properties();
    if (new java.io.File(propertiesFilePath).exists()) {
        try (java.io.FileInputStream in = new java.io.FileInputStream(propertiesFilePath)) {
            prop.load(in);
        }
        catch (java.io.FileNotFoundException ex) { System.err.println(ex); }
        catch (java.io.IOException ex) { System.err.println(ex); }
    }
    
    try (java.io.FileOutputStream outputStream = new java.io.FileOutputStream(propertiesFilePath)) {
        prop.setProperty(propertyName, value);
        prop.store(outputStream, null);
        outputStream.close();
        return true;
    }
    catch (java.io.FileNotFoundException ex) {
        System.err.println(ex);
    }
    catch (java.io.IOException ex) {
        System.err.println(ex);
    }
    return false;
}   

If you don't already contain a specific properties file then it would be a good idea to call the above method as soon as the application starts (perhaps after initialization) so that you have default values to play with if desired, for example:

if (!new File("config.properties").exists()) {
    setProperty("config.properties", "ApplicationRunCount", "0");
}

The above code checks to see if the properties file named config.properties already exists (you should always use the .properties file name extension). If it doesn't then it is created and the property name (Key) is applied to it along with the supplied value for that property. Above we are creating the ApplicationRunCount property which is basically for your specific needs. When you look into the config.properties file created you will see:

#Mon Sep 28 19:07:08 PDT 2020
ApplicationRunCount=0

The getProperty() Method:

This method can retrieve a value from a specific property name (key). Whenever you need the value from a particular property contained within your properties file then this method can be used:

public static String getProperty(String propertiesFilePath, String key) {
    try (java.io.InputStream ips = new java.io.FileInputStream(propertiesFilePath)) {
        java.util.Properties prop = new java.util.Properties();
        prop.load(ips);
        return prop.getProperty(key);
    }
    catch (java.io.FileNotFoundException ex) { System.err.println(ex); }
    catch (java.io.IOException ex) { System.err.println(ex); }
    return null;
}

Your Task:

What is confusing here is you say you want to keep track of the number of times your Program is run yet you increment your counter variable named count within a method named doMethod(). This would work if you can guarantee that this method will only run once during the entire time your application runs. If this will indeed be the case then you're okay. If it isn't then you would possibly get a count total that doesn't truly represent the actual number of times your application was started. In any case, with the scheme you're currently using, you could do this:

public class CounterTest {

    // Class Constructor
    public CounterTest() {
        /* If the config.properties file does not exist
           then create it and apply the ApplicationRunCount
           property with the value of 0.             */
        if (!new java.io.File("config.properties").exists()) {
            setProperty("config.properties", "ApplicationRunCount", "0");
        }
    }
    
    public static void main(String[] args) {
        new CounterTest().doMethod(args);
    }

    private void doMethod(String[] args) {
        int count = Integer.valueOf(getProperty("config.properties", 
                                                "ApplicationRunCount"));
        count++;
        setProperty("config.properties", "ApplicationRunCount", 
                    String.valueOf(count));
        System.out.println(count);
    }

    public static String getProperty(String propertiesFilePath, String key) {
        try (java.io.InputStream ips = new 
                           java.io.FileInputStream(propertiesFilePath)) {
            java.util.Properties prop = new java.util.Properties();
            prop.load(ips);
            return prop.getProperty(key);
        }
        catch (java.io.FileNotFoundException ex) { System.err.println(ex); }
        catch (java.io.IOException ex) { System.err.println(ex); }
        return null;
    }

    public static boolean setProperty(String propertiesFilePath,
                                      String propertyName, String value) {
        java.util.Properties prop = new java.util.Properties();
        if (new java.io.File(propertiesFilePath).exists()) {
            try (java.io.FileInputStream in = new java.io.FileInputStream(propertiesFilePath)) {
                prop.load(in);
            }
            catch (java.io.FileNotFoundException ex) { System.err.println(ex); }
            catch (java.io.IOException ex) { System.err.println(ex); }
        }
    
        try (java.io.FileOutputStream outputStream = new java.io.FileOutputStream(propertiesFilePath)) {
            prop.setProperty(propertyName, value);
            prop.store(outputStream, null);
            return true;
        }
        catch (java.io.FileNotFoundException ex) {
            System.err.println(ex);
        }
        catch (java.io.IOException ex) {
            System.err.println(ex);
        }
        return false;
    }
}

Whenever you start your application you will see the run count within the Console Window. Other useful methods might be removeProperty() and renameProperty(). Here they are:

/**
 * Removes (deletes) the supplied property name from the supplied property 
 * file.<br>
 * 
 * @param propertiesFilePath (String) The full path and file name of the 
 * properties file you want to remove a property name from.<br>
 * 
 * @param propertyName (String) The property name you want to remove from 
 * the properties file.<br>
 * 
 * @return (Boolean) Returns true if successful and false if not.
 */
public static boolean removeProperty(String propertiesFilePath,
                                  String propertyName) {
    java.util.Properties prop = new java.util.Properties();
    if (new java.io.File(propertiesFilePath).exists()) {
        try (java.io.FileInputStream in = new java.io.FileInputStream(propertiesFilePath)) {
            prop.load(in);
            prop.remove(propertyName);
        }
        catch (java.io.FileNotFoundException ex) { System.err.println(ex); return false; }
        catch (java.io.IOException ex) { System.err.println(ex); return false; }
    }
    
    try (java.io.FileOutputStream out = new java.io.FileOutputStream(propertiesFilePath)) {
        prop.store(out, null);
        return true;
    }
    catch (java.io.FileNotFoundException ex) { System.err.println(ex); }
    catch (java.io.IOException ex) { System.err.println(ex); }
    return false;
}

/**
 * Renames the supplied property name within the supplied property file.<br>
 * 
 * @param propertiesFilePath (String) The full path and file name of the 
 * properties file you want to rename a property in.<br>
 * 
 * @param oldPropertyName (String) The current name of the property you want 
 * to rename.<br>
 * 
 * @param newPropertyName (String) The new property name you want to use.<br>
 * 
 * @return (Boolean) Returns true if successful and false if not.
 */
public static boolean renameProperty(String propertiesFilePath, String oldPropertyName,
                                     String newPropertyName) {
    String propertyValue = getProperty(propertiesFilePath, oldPropertyName);
    if (propertyValue == null) { return false; }
    
    java.util.Properties prop = new java.util.Properties();
    if (new java.io.File(propertiesFilePath).exists()) {
        try (java.io.FileInputStream in = new java.io.FileInputStream(propertiesFilePath)) {
            prop.load(in);
            prop.remove(oldPropertyName);
        }
        catch (java.io.FileNotFoundException ex) { System.err.println(ex); return false; }
        catch (java.io.IOException ex) { System.err.println(ex); return false ;}
    }
    
    try (java.io.FileOutputStream out = new java.io.FileOutputStream(propertiesFilePath)) {
        prop.store(out, null);
    }
    catch (java.io.FileNotFoundException ex) { System.err.println(ex); return false; }
    catch (java.io.IOException ex) { System.err.println(ex); return false; }
    
    return setProperty(propertiesFilePath, newPropertyName, propertyValue);
}
DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
  • This is extremely helpful. I actually already have config.properties file located in my project path /project/src/test/resources/testconfig.properties where i am specifying my data and reading the values using testConfig.get("applicationcount"). I just need to update those data every time i run the program so i get the latest count. I will try your suggestion and work on it. If you have any recommendation on how I can make use of my existing property file just let me know. Thanks a lot for the suggestion. :-) – Sam1977 Sep 29 '20 at 12:05
  • Hello, I am able to increase the counter but when i am trying to add another field called AmountDue in config.property file, its not taking it. Everytime i run the program it only shows ApplicationRuncount field only. I want to add amoutDue and startdate fields in the config.property file and increase those numbers as well when program runs. How do i do that? – Sam1977 Sep 29 '20 at 15:59
  • @Sam1977, I fixed the `setProperty()` method.Rreplace the old **setProperty()** method with the new one provided in the code above. You should be able to add whatever properties you like. – DevilsHnd - 退職した Sep 30 '20 at 06:24
1

Try this.

public class CounterTest {

    static final Path path = Path.of("counter.txt");
    int count;

    CounterTest() throws IOException {
        try {
            count = Integer.valueOf(Files.readString(path));
        } catch (NoSuchFileException | NumberFormatException e) {
            count = 0;
        }
    }

    public void doMethod() throws IOException {
        ++count;
        System.out.println(count);
        Files.writeString(path, "" + count);
    }

    public static void main(String[] args) throws IOException {
        CounterTest c = new CounterTest();
        c.doMethod();
    }

}
0

You can't the only way is to use a Database or simpler use a txt file to save the number and every time you run your app reads the txt file and gets the number.

Here is How to do it:

This is the Main class:

package main;
    
import java.io.File;
import java.io.IOException;
    
public class Main {
    public static void main(String[] args) {
        String path = "C:\\Example.txt";
        int number = 0;
        try {
            ReadFile file = new ReadFile(path);
            String[] aryLines = file.OpenFile();
            try {
                number = Integer.parseInt(aryLines[0]);
            } catch (Exception e) {
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        System.out.println(number);
        number++;
        
        File txtfile = new File(path);
        if (txtfile.exists()) {
            txtfile.delete();
            
            try {
                txtfile.createNewFile();
                WriteFile data = new WriteFile(path, true);
                data.writeToFile(number + "");
            } catch (IOException ex) {
            }
        } else {
            try {
                System.out.println("no yei");
                txtfile.createNewFile();
                WriteFile data = new WriteFile(path, true);
                data.writeToFile(number + "");
            } catch (IOException ex) {
            }
        }
    }
}

the class that writes anything you need:

package main;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;

public class WriteFile {

    public String path;
    public boolean append_to_file = false;

    public WriteFile(String file_path) {
        path = file_path;
    }

    public WriteFile(String file_path, boolean append_value) {
        path = file_path;
        append_to_file = append_value;
    }

    public void writeToFile(String textline) throws IOException {
        FileWriter write = new FileWriter(path, append_to_file);
        PrintWriter print_line = new PrintWriter(write);

        print_line.printf("%s" + "%n", textline);
        
        print_line.close();
    }
}

And this one is the one that gets the text on the file:

package main;

import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;

public class ReadFile {
    private static String path;
    
    public ReadFile(String file_path){
        path = file_path;
    }
    public String[] OpenFile() throws IOException {
        FileReader fr = new FileReader(path);
        BufferedReader textReader = new BufferedReader(fr);
        
        int numberOfLines = readLines();
        String[] textData = new String[numberOfLines];
        
        for (int j = 0; j < numberOfLines; j++) {
            textData[j] = textReader.readLine();
        }
        
        textReader.close();
        return textData;
    }
    static int readLines() throws IOException {
        FileReader file_to_read = new FileReader(path);
        BufferedReader bf = new BufferedReader(file_to_read);
        
        String aLine;
        int numberOfLines = 0;
        
        while((aLine = bf.readLine()) != null){
            numberOfLines++;
        }
        bf.close();
        return numberOfLines;
    }
}
Holis
  • 175
  • 1
  • 10
  • That is a really old and cumbersome way of dealing with files. use NIO to replace your code with just a few one-liners instead. – Zabuzard Sep 30 '20 at 06:32