Writing and reading files using Java

Well,
I’m using Java (in vscode) to program my robot, and I’m trying to collect some information from the last run of the robot (like controller input ,boolean values etc…) and save them in a txt file .
it keeps giving me “access errors” and FileNotFound exceptions, I saw some solutions that recommend to put the full path of the directory that I want to save the file to, and that also didn’t solve the problem.
Code:
public String Path = “D:\FRC\Save.txt”;//full path out of the robot directory…
saveData D1 = new saveData();

//////////////////////////
try {

  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(Path));

  out.writeObject(D1);
  out.close();

} catch (FileNotFoundException e) {

  e.printStackTrace();
} catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

/////////////////////////////
explanation:
As I said before I want to save some data about the robot when it runs so I created a custom Class called : “saveData”, I enter all of the information that I want to save during the running phase of the robot into D1(saveData object), and then I click on a button with the XboxController to save the file to the assigned path, and the code above ^^^ represents the saving process…
Any suggestion?

Remember that your code is running on the roboRIO, so using Linux. Things like D: and the backslash are specific to Windows.

I recommend that you just save in “data.txt”, and then get the file off the robotRIO using FTP.

For a more robust solution, call your file something like:

String.format("data-%s.txt", new Date())

This will create a new file each time.

2 Likes

Okayy…
but I think I’ve tried it before and it didn’t work, I’ll try it again.
if it keeps giving me these errors and exceptions, what can I do about them?

Could you be more specific about the errors and exceptions you’re seeing?

Just to be crystal-clear, the robot code, running on the roboRIO, has absolutely no access to the file system on your laptop. It cannot save files there. It can only save files on its local (Unix) file system.

1 Like

Okay ty I’ll try them…

something like this :
java.io.FileNotFoundException: Save.txt (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(FileOutputStream.java:179)
at java.io.FileOutputStream.(FileOutputStream.java:131)

And what path were you using?

I tried this alone “Save.txt”
and this “D:\FRC\Save.txt”
and both gave me the same result

As an alternative, consider publishing this information to SmartDashboard instead.

Or just print the data using System.out.println("my msg here"); and view it in the rio log.

Try /home/lvuser/data.txt

3 Likes

You can store data that persists across reboots using the WPILib Preferences class. This is definitely easier than file IO, but it’s a key/value store that can only store primitive data types + String, so it will not work for certain types of data.

I don’t think they’re looking to persist data between runs, but to get debug info.

1 Like

Ah, my bad I read too quickly. I will leave my response for anybody in the future who may possibly find this thread looking for such a thing though

You might also want to look at:

1 Like

If it is an access issue they may need to change the permissions of “save.txt”

The default current working directory (which is where an unadorned “save.txt” will be written) for Java programs on the Rio is not /home/lvuser, and is not writable. To get a directory that will work and be writable in both simulation and on the RoboRIO, use edu.wpi.first.wpilibj.Filesystem.getOperatingDirectory().

3 Likes

Here’s a hint about writing to a flash drive. (I haven’t tried it since I’ve used NT to a JFreeChart program with an NT listener in it on my PC. Or scp to retrieve roboRIO files that this thread shows how to create.)

2 Likes

useful information

Curiosity got the better of me and someone read my post so I had to find out how this worked. I’m no Linux guru or wizard but there is a link from U, u, C, (c) to various folders (just to placate Windows users?). If you plug in a flash drive formatted NTFS you get read only to /media/sda which is /dev/sda or U or u. If you plug in a flash drive formatted FAT you get read/write /media/sda1 which is /dev/sda1 or U or u.

ls -lta U u C c

lrwxrwxrwx 1 admin administ 2 Jul 1 2021 C → /c/
lrwxrwxrwx 1 admin administ 11 Dec 31 1969 U → /media/sda1/
lrwxrwxrwx 1 admin administ 11 Dec 31 1969 u → /media/sda1/

c:
total 12
drwxrwxr-x 3 lvuser ni 4096 Jul 1 2021 ./
lrwxrwxrwx 1 lvuser ni 22 Jul 1 2021 README_File_Paths.txt → /README_File_Paths.txt
lrwxrwxrwx 1 lvuser ni 25 Jul 1 2021 README_File_Transfer.txt → /README_File_Transfer.txt
drwxrwxr-x 2 lvuser ni 4096 Jul 1 2021 ni-rt/
drwxr-xr-x 21 admin administ 4096 Dec 31 1969 …/

I tried hard but could not figure out a way to get NTFS writable but FAT works fine.

The Java code in the link I provided about memory usage apparently needs to be updated. I got this to work but not sure it’s very efficient. I didn’t bother fussing with the “log” folder in the original posting - more work:

private final Path memoryLog = Path.of("/U/memorytable.csv");

private void logMemoryUse() {
try {
var temp = System.currentTimeMillis() + “,” + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() + “\n”);
Files.writeString(memoryLog, temp, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (IOException e) {
// Couldn’t write to the file – handle it how you want
System.out.println(e);
}
}

logMemoryUse();