File Copy Method (Efficiency Question)

Discussion in 'Spigot Plugin Development' started by Hunky524, May 4, 2017.

  1. The following method is used when I want to copy an internal file that is included within the jar file to an external config file. This allows me to create initial config files with commented lines in any style that I want.

    The method works, but I am only wondering if anyone might have ideas on ways to optimize the method or a different way of going about this problem entirely.

    Method:
    Code (Java):
    public void copyPremadeConfig(InputStream input) throws IOException, InvalidConfigurationException {
            if (input == null)
                return;
            if (!isFirstLoad())
                return;
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            StringBuilder textToAdd = new StringBuilder();
            while(true) {
                String newLine;
                newLine = reader.readLine();
                if (newLine == null)
                    break;
                textToAdd.append(newLine);
                textToAdd.append('\n');
            }
            FileWriter fileWriter =  null;
            BufferedWriter bufferedWriter = null;
            try {
                fileWriter = new FileWriter(file);
                bufferedWriter = new BufferedWriter(fileWriter);
                bufferedWriter.write(textToAdd.toString());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bufferedWriter != null)
                    bufferedWriter.close();
                if (fileWriter != null)
                    fileWriter.close();
            }
            reader.close();
            load(file);
        }
    The 'isFirstLoad()' method call near the top determines if the file already exists essentially to avoid rewriting an already existing config file, and the load method at the bottom is the method form the Spigot FileConfiguration class which loads the config data from a given file.

    If I were to call this method, it would look something like this:
    Code (Java):
    myConfigObject.copyPremadeConfig(this.getClass.getResourceAsStream("/resources/config.yml"));
    Any critical feedback or suggestions are always welcome. :)
     
  2. You're overcomplicating it, the java.nio stuff has Files#copy to copy the contents of an InputStream to a Path, that's all you need
     
    • Agree Agree x 1
  3. This is what I use

    https://hub.spigotmc.org/javadocs/spigot/org/bukkit/plugin/java/JavaPlugin.html#saveResource(java.lang.String, boolean)

    From my CommandInterpreter example code:
    https://www.spigotmc.org/resources/command-interpreter.37560/

    Code (Text):
        // load the commands file which maps the methods
        path = getDataFolder().toString();
        comPath = Paths.get(path, commandsFile);
        commandsf = new File(comPath.toString());
        if (!commandsf.exists()) {
          commandsf.getParentFile().mkdirs();
          if (getResource(commandsFile) != null) {
            saveResource(commandsFile, false);
          } else {
            try {
              commandsf.createNewFile();
            } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
          }
        }
     
  4. Ahhhh, that definitely is much simpler. Thanks.
     
  5. Why don't you simply use the 'saveResource(String.class)' method in the JavaPlugin.class ?
     
  6. Well, if I were to use FileUtils for copying a file, then I would be using an entire dependency for just a single method. A similar method is already included in the standard Java JDK as @Redrield pointed out. Just seems a bit unnecessary to use the dependency when I don't need to. Thanks for the suggestion though. :)
     
  7. The way I am designing my Config API allows the ability to create config files that are not located within the plugin's data folder. The saveResource method can only copy files to the plugin's data folder, hence the issue using that method. If I didn't need to access config files outside of the plugin's data folder, then I would just use saveResource.
     
  8. You can also just look how the method 'saveResource' does work and re-create it. Here is a link to it.
     
    • Agree Agree x 1
  9. Considering Commons IO is packaged with Spigot, no, you wouldn't be.
     
  10. The fact of the matter is that it isn't necessary. The standard lib has what he needs

    Sent from my Nexus 5 using Tapatalk
     
  11. Choco

    Moderator

    FileUtils#copyInputStreamToFile() - A method provided by Commons IO, a 3rd party API shaded into Spigot
    Files#copy() - A method provided by the stdlib (the JDK). Literally built-in to Java

    Reinventing the wheel isn't really an issue here. Using either one is preference. I've never done any benchmarks on these methods so I couldn't tell you which one does it better, but is there really any reason to use the method provided by a 3rd party library when you can just use a method that already exists in the JDK? What if Commons IO were removed from Spigot's shading? Unlikely, but what if. You would then have to end up updating your resource to find an alternative, that being Files#copy(). You might as well just use the method provided by the JDK if it's available.
    (This is essentially the point that @Redrield was trying to get across)
     
    • Like Like x 2
    • Agree Agree x 1
    • Winner Winner x 1
    • Optimistic Optimistic x 1
  12. konsolas

    Supporter

    It's worth mentioning that the NIO library is designed for more intensive file operations. At worst, Files#copy just copies stream to stream, with a buffer of size 8192. Otherwise, it directly calls operating system methods which can be much more efficient (although this is not guaranteed in the documentation).

    Apache FileUtils only supports stream-to-stream copying, with a buffer size of 4096.

    [/less important point than the "it's part of the jdk" one by @2008Choco which is probably the main thing that matters here as performance diff. is negligible for config files]
     
    • Agree Agree x 1
    • Informative Informative x 1