A Little Help With Files

Discussion in 'Plugin Development' started by PandazNWafflez, May 24, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    PandazNWafflez

    I wish to read from a file, but not a YML file, I want to read from a .TXT file, it needs to read one entry per line and I need to have a way to set a line with code.

    Anyone know how I could do this?
     
  2. I have some functions which read the file, but i am not sure about the writing, i'll look.
    greetz blackwolf12333
    EDIT: do you want to read the file, and then print the output of the read function to the player?
    or do you want to read the file to a String Array, and then use the String Array for something?
     
  3. Offline

    PandazNWafflez

    I want to check if a file contains a player's name, and send certain players a message if the file does.

    BTW I made a pull request on your plugin :) You had the file that plugins using it were supposed to implement as a class not an interface.
     
  4. Ehm, what do i do with an pull request, i have 0% experience with github:p
    greetz blackwolf12333
     
  5. Offline

    PandazNWafflez

    Click merge. But do you know how to do this?
     
  6. Ehm about the API, you didn't have to change that:p, i am gonna change that whole thing this weekend, and i just wrote a function which deletes a line you specify, is not on github btw, do you want me to post it here?
    greetz blackwolf12333
     
  7. Offline

    PandazNWafflez

    I don't want to delete it, just get it, and I want to search the whole file not check a single line. But anything that might give me a lead on how to do it would be nice.
     
  8. Ok, i have a few functions for that too, just look in the FileUtils file on github: https://github.com/blackwolf12333/G.../blackwolf12333/grieflog/utils/FileUtils.java

    greetz blackwolf12333
    EDIT: just found out that i have a better function for that, which is not on github...
     
  9. Offline

    PandazNWafflez

  10. Sure

    Code:
    /**
        * @param file: the file to read the lines of
        * @param text: this specifies which lines you want in the output, if a line contains this text the line will be added
        * @return This returns a String[] of the lines which contain the searched text
        */
        public String[] readLines(File file, String text)
        {
            String[] lines = new String[count(file)];
            String currentline = "";
           
            if(!file.exists())
            {
                System.out.print("Failed to open file!");
            }
            try {
                BufferedReader in = new BufferedReader(new FileReader(file));
               
                for(int i = 0; (currentline = in.readLine()) != null; i++)
                {
                    if(currentline.indexOf(text) > 0)
                    {
                        lines[i] = currentline;
                    }
                    else
                    {
                        lines[i] = null;
                    }
                }
               
                in.close();
            } catch(Exception e) {
                System.out.print(e.getMessage());
            }
           
            return lines;
        }
    for this to work you also need this:
    Code:
    /**
        * @param file: the file to count the lines from
        * @return Returns the number of lines the file has, if the lines could not be counted, it returns -1
        */
        @SuppressWarnings("unused")
        public int count(File file)
        {
            try {
                LineNumberReader reader = new LineNumberReader(new FileReader(file));
                int count = 0;
                String lineRead = "";
                while((lineRead = reader.readLine()) != null) {}
                count = reader.getLineNumber();
                reader.close();
                return count;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return -1;
        }
    greetz blackwolf12333:)
     
  11. Offline

    PandazNWafflez

    Would that return multiple lines then? Because I only want to return one, or it would break.
     
  12. if your file contains only one line with the thing you search for, it will only return one line, as lines[0]
     
  13. Offline

    PandazNWafflez

    Hmm, I'd better add a check to see if it's a duplicate.
     
  14. Offline

    Everdras

    Correct me if I'm wrong, but since you just directly pass the BufferedReader a new instance of FileReader, you have no reference to the FileReader object and as such are unable to close its underlying streams. This can corrupt the files or, on some systems (Windoze), keep a lock on them active and make subsequent attempts to stream from the file fail.
     
  15. Hmm, ok, i'll change that, i didn't really think about it:p, thanks
    greetz blackwolf12333
     
  16. Offline

    PandazNWafflez

    Hey, sorry about this, the writing to the file is working now, but the reading doesn't do anything. I tried modifying it a little. This is what I have now.

    Code:
    private boolean isOnList(String text, File file) {
    if (readLines(file, text).equalsIgnoreCase(text)) {
    return true;
    }
    return false;
    }
     
    private String readLines(File file, String text) {
            String[] lines = new String[count(file)];
            String currentline = "";
           
            if(!file.exists()) {
                System.out.print("Failed to open file!");
            }
            try {
           FileReader bufferedFileReader = new FileReader(ListFile);
                BufferedReader in = new BufferedReader(bufferedFileReader);
               
                for(int i = 0; (currentline = in.readLine()) != null; i++) {
                    if(currentline.indexOf(text) > 0) {
                        lines[i] = currentline;
                    } else {
                        lines[i] = null;
                    }
                }
                bufferedFileReader.close();
                in.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            return lines[0];
        }
     
    private int count(File file) {
            try {
           FileReader lineNumberFileReader = new FileReader(ListFile);
                LineNumberReader reader = new LineNumberReader(lineNumberFileReader);
                int count = 0;
                String lineRead = "";
                while((lineRead = reader.readLine()) != null) {}
                count = reader.getLineNumber();
                reader.close();
                lineNumberFileReader.close();
                return count;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }
    
    But checking with isOnList(String, File) doesn't work either on the check command or when a player joins. This is what I have for those situations:

    Please note unnecessary parts have been skipped.

    Player Join:
    Code:
    if (isOnList(player.getName(), ListFile)) {
    for (Player onlinePlayer : player.getServer().getOnlinePlayers()) {
    if (onlinePlayer.hasPermission("warnlist.notify")) {
    }
    }
    
    Command:
    Code:
    if (split[0].equalsIgnoreCase("check")) {
    if (!sender.hasPermission("warnlist.check") && !(sender instanceof ConsoleCommandSender)) {
    sender.sendMessage(ChatColor.RED + "You don't have permission to do that!");
    }
    if (isOnList(split[1], ListFile)) {
    sender.sendMessage(ChatColor.RED + "That player is a bad player!");
    } else {
    sender.sendMessage(ChatColor.RED + "That player is not a bad player!");
    }
    
     
  17. Your onList function is not doing what you want it to do:p
    The listfile you have, does that only have one line in which the player name is in, because if that's true, you can just simply modify the readlines function to only return that line or return null.
    greetz blackwolf12333
     
  18. Offline

    PandazNWafflez

    I have tried with multiple lines and a single line. Neither work. And I don't really get what you mean.
     
  19. Well, if your file, which you search through, and you search through it for a player name, and that file contains only one line which contains the player name, you can modify the readLines to only return that one line, and then your onList function should work. greetz blackwolf12333
     
  20. Offline

    Njol

    The BufferedReader of course still has a reference to the FileReader, and it's close() method cannot do much more than call filereader.close() (see also: http://stackoverflow.com/questions/4976162/java-buffers-and-streams-releasing-underlying-resources)

    @op:
    Since reading a file can be slow, it should only be done once (if it isn't modified in the meantime), thus you should simply read the whole file in onEnable and store it in a List<String>. This also allows you to easily check whether a player is in the file with list.contains(player.getName()).

    Sample implementation:
    Code:
    // the list:
    private List<String> list = new ArrayList<String>();
     
    // in onEnable:
    BufferedReader r = new BufferedReader(new FileReader(file));
    String line;
    while ((line = r.readLine()) != null)
        list.add(line);
     
    // to check whether a player is in the file:
    list.contains(player.getName());
     
    // if you modify the list in the meantime you can save it in onDisable like this:
    PrintWriter w = new PrintWriter(file);
    for (String line:list)
        w.println(line);
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 26, 2016
  21. Offline

    PandazNWafflez

    I need to add players to the file with commands. However I could use list.add(split[1]);, I suppose, so I'll go with that, thanks!

    It throws a few exceptions though, so I ended up with this:

    Code:
    private void readLines(File file, String text) {
    if (!file.exists()) {
          try {
              file.createNewFile();
                } catch (IOException ex1) {
              ex1.printStackTrace();
                }
    }
    BufferedReader r = null;
            try {
          r = new BufferedReader(new FileReader(file));
            } catch (FileNotFoundException ex) {
          ex.printStackTrace();
            }
    String line;
    try {
    if (r == null) {
    r = new BufferedReader(new FileReader(file));
    }
          while ((line = r.readLine()) != null)
              badPlayers.add(line);
            } catch (IOException ex) {
          ex.printStackTrace();
            }
        }
    
    And the onDisable() looks like this:

    Code:
    @Override
    public void onDisable() {
    PrintWriter w = null;
    if (!ListFile.exists())
           try {
               ListFile.createNewFile();
                } catch (IOException ex1) {
               ex1.printStackTrace();
                }
            try {
           w = new PrintWriter(ListFile);
            } catch (FileNotFoundException ex) {
           ex.printStackTrace();
            }
    for (String line : badPlayers)
       w.println(line);
    }
    
     
  22. Offline

    Njol

    I think you should not try to read/write anything if the file has not been found ;), thus I suggest a modified version of your code (it's basically just bits of code shifted around, but I also added 2 'finally' blocks to close the streams if any error occurrs):
    Code:
        private void readLines(File file, String text) {
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException ex1) {
                    ex1.printStackTrace();
                }
            }
            BufferedReader r = null;
            try {
                r = new BufferedReader(new FileReader(file));
                String line;
                while ((line = r.readLine()) != null)
                    badPlayers.add(line);
            } catch (FileNotFoundException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally { // good practice
                if (r != null)
                    r.close();
            }
        }
    Code:
        public void onDisable() {
            PrintWriter w = null;
            if (!ListFile.exists())
                try {
                    ListFile.createNewFile();
                } catch (IOException ex1) {
                    ex1.printStackTrace();
                }
            try {
                w = new PrintWriter(ListFile);
                for (String line : badPlayers)
                    w.println(line);
            } catch (FileNotFoundException ex) {
                ex.printStackTrace();
            } finally { // good practice
                if (w != null)
                    w.close();
            }
        }
     
  23. Offline

    PandazNWafflez

    Ok, I'll use this. Thanks!
     
Thread Status:
Not open for further replies.

Share This Page