Solved for loop readline != null always returning null

PleasantRain

New member
Dec 7, 2022
2
0
1
I've been trying to make a nickname plugin.

what i expected my code to do:
attempt to read a csv file line-by-line
check if player who called the command is already on file
if they are: replace their old nickname with new one from arguments by swapping the current line with a new player, nickname line
append line to StringBuilder
after checking all lines if player wasn't on file append new entry
write over file with StringBuilder converted to string

however what happens is:
skips over line reading/writing
appends "new entry"
writes over entire file with just the single "new entry"

it skips the loop (and the code in it) regardless of if the player is or isn't already on file, or if/how many entries i manually insert beforehand.

ive tried to get it to not skip in any capacity by:
using a while loop instead of the for loop ( while ((line = reader.readline()) != null) ),
removing the if from inside the loop,
using a plain text file instead of a csv,
swapping double backslash "\\" with single forward slash "/" in file path string,
and probably some other stuff but i can't remember because ive literally been losing sleep trying to fix this or get some idea of why.

from my searching online, I think my code "should" "theoretically" work,
but ive only been learning java, mod making, and programming in general for the past week and a bit so its half bashing my head against a wall and half thinking I have gained some understanding only for it not to be any solution to this problem.
also please be gentle.

btw the system outs were for troubleshooting and wouldn't be final

the actual code:
Java:
onCommand(){
 Player player = (Player) sender
 if(args[0].contains("set"))
  try{
   String nickname = args[1]
   String playerNickname = player.getName() + nickname
   BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, false));
   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   System.out.println("searching for player in nickname registry");
   StringBuilder stringBuilder = new StringBuilder();
   boolean playerEntryReplaced = false;
   for(String line = reader.readLine(); line != null; line = reader.readLine()){ //I'm pretty sure the problem is here
     System.out.println("current line: " + line);
     if(line.contains(playerName)){
      System.out.println("player entry exists; replacing nickname");
      stringBuilder.append(playerNickname).append('\n');
      playerEntryReplaced = true;
     } else{
      stringBuilder.append(line);
     }
     System.out.println(line);
   }
   if(!playerEntryReplaced){
    System.out.println("player entry doesn't exist; creating entry");
    stringBuilder.append(playernickname).append('\n');
   }
   String fileAsString = stringBuilder.toString();
   System.out.println("nickname registry contains: " + fileAsString);
   reader.close();
   writer.write(fileAsString);
   writer.close();
   player.sendMessage("your nickname has been updated to " + nickname);
   }catch(IOException e){
    System.out.println("player nickname write error");
    e.printStackTrace();
 }
}
I know its generally a good idea to give commands their own seperate classes, however this plugin will only have two commands and they will share alot of variables so I thought it could work fine.
 
Last edited:

PleasantRain

New member
Dec 7, 2022
2
0
1
Okay, I took a step back and tried to use a line read/write in a blank project and got it to work. I then went back to my main project and seperated the commands into their own classes without the hamfisted "if"s and now it works as expected. no more skipping over the loop.
lesson learned: if something is standard there is usually a good reason.
I'm still kind of unsure why it wouldn't work if the loop is in one "if" so if anyone does read this and can elaborate I would be very appreciative.
 

stefvanschie

Moderator
Staff member
Dec 17, 2021
97
3
16
8
There's nothing wrong with putting a for loop inside an if statemenet, although it is generally better to separate different commands into different methods/classes to avoid cluttering up your code. Perhaps you were reading data from the wrong file?