-1

The image below shows the format of my settings file for a web bot I'm developing. If you look at line 31 in the image you will see it says chromeVersion. This is so the program knows which version of the chromedriver to use. If the user enters an invalid response or leaves the field blank the program will detect that and determine the version itself and save the version it determines to a string called chromeVersion. After this is done I want to replace line 31 of that file with

"(31) chromeVersion(76/77/78), if you don't know this field will be filled automatically upon the first run of the bot): " + chromeVersion

To be clear I do not want to rewrite the whole file I just want to either change the value assigned to chromeVersion in the text file or rewrite that line with the version included.

Any suggestions or ways to do this would be much appreciated.

image

  • The correct way to do this is to load the entire file, make your changes, then save it all back. You can't make changes to a file as you're reading it. – killjoy Oct 21 '19 at 19:13
  • there are a few ways to do this, but you might consider using a properties file instead. That way you have key value pairs and you'd just call setProperty(String key, String value) and java will update the value if the key already exists: https://docs.oracle.com/javase/tutorial/essential/environment/properties.html – pcalkins Oct 21 '19 at 21:52
  • also if you are going to write passwords and/or credit card#s to disk, be sure to encrypt/decrypt them using a key specific to the machine they are saved on. – pcalkins Oct 21 '19 at 21:55
  • @pcalkins in regards to encrypting/decrypting do you have any knowledge in that area or should I do some research? –  Oct 21 '19 at 22:06
  • this is what I use for encrypt/decrypt: https://github.com/pcalkins/browsermator/blob/master/src/browsermator/com/Protector.java Encrypt on write, decrypt on load. You can get your machine's serial number and use that for or as part of the "PASSWORD". – pcalkins Oct 21 '19 at 22:25
  • Getting your machine's serial number: https://stackoverflow.com/questions/1986732/how-to-get-a-unique-computer-identifier-in-java-like-disk-id-or-motherboard-id – pcalkins Oct 21 '19 at 22:28

1 Answers1

1

You will need to rewrite the whole file, except the byte length of the file remains the same after your modification. Since this is not guaranteed to be the case or to find out is too cumbersome here is a simple procedure:

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class Lab1 {

    public static void main(String[] args)  {
            String chromVersion = "myChromeVersion";
        try {
            Path path = Paths.get("C:\\whatever\\path\\toYourFile.txt");
            List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
            int lineToModify = 31;
            lines.set(lineToModify, lines.get(lineToModify)+ chromVersion);
            Files.write(path, lines, StandardCharsets.UTF_8);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Note that this is not the best way to go for very large files. But for the small file you have it is not an issue.

Eritrean
  • 15,851
  • 3
  • 22
  • 28
  • if you know the line number this is good. if you know the property you can check each item in the list with pattern matching then alter that element and write all back. – mavriksc Oct 21 '19 at 19:21
  • 1
    `String lineToChange = lines.stream().filter(s-> s.contains("chromeVersion")).findFirst().orElse(""); if(!lineToChange.isEmpty()){ lines.set(lines.indexOf(lineToChange),detectedVer); }` – mavriksc Oct 21 '19 at 19:35
  • @mavriksc Thanks for your addition. – Eritrean Oct 21 '19 at 19:39
  • 1
    Thanks, it works well, I don't think anything more complex is needed for such a small file. also, correct me if I'm wrong, is the reason it is not great for large files due to `.readAllLines` causing a `java.lang.OutOfMemoryError` –  Oct 21 '19 at 22:02
  • Yes, that is correct. The problem with this approach is that all the file lines are kept in memory – which will quickly lead to OutOfMemoryError if the File is large enough.To avoid this you need to use some streaming technicks/ 3rd party library like `Apache Commons IO` which provides a LineIterator allowing for processing of each line – without keeping references to them – and in conclusion, without keeping them in memory. – Eritrean Oct 21 '19 at 22:21