FileSQL - Share files between servers on the same computer

Discussion in 'Resources' started by SoThatsIt, Sep 16, 2013.

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

    SoThatsIt

    hey guys while in the process of attempting to get a mysql server to work with the server i dev for, the owner of the server suggested to me to use files instead of mysql as the servers we were trying to connect were on the same computer. one major advantage of using files is its quicker than sending requests to a mysql server, especially if you are sending lots of requests. I then thought, wouldnt it be a little inefficient having to read a very large file every time you attempt to read 1 value? that is why this will create 1 file for each value. Here is the code:

    FileSQL.java
    Code:
    package me.sothatsit.lgcore;
     
    import java.io.EOFException;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
     
    public class FileSQL {
       
        public File dir;
       
        public FileSQL(File dir){
            this.dir=dir;
            if(!dir.exists()){
                dir.mkdirs();
            }
        }
       
        public Value getValue(String name){
            Value v = new Value(name);
            v.load(dir);
            return v;
        }
       
        public String getValue(String name, String header){
            Value v = new Value(name);
            v.load(dir);
            return v.getValue(header);
        }
       
        public File getDir(){
            return dir;
        }
       
        public class Value{
           
            private String name;
            private String[][] values;
           
            public Value(String name){
                this.name=name;
                this.values=new String[0][0];
            }
           
            public Value(String name, String[][] values){
                this.name=name;
                this.values=values;
            }
           
            public String getValue(String header){
                int index = -1;
                for(int i=0; i<this.values.length; i++){
                    if(this.values[i][0].equals(header)){
                        index = i;
                        break;
                    }
                }
                if(index != -1)return this.values[index][1];
                else return null;
            }
           
            public void setValue(String header, String value){
                int index = -1;
                for(int i=0; i<this.values.length; i++){
                    if(this.values[i][0].equals(header)){
                        index = i;
                        break;
                    }
                }
                if(index == -1){
                    //create new column with value
                    String[][] values = new String[this.values.length+1][2];
                    for(int i=0; i<this.values.length; i++){
                        values[i] = this.values[i];
                    }
                    values[values.length-1]=new String[] {header, value};
                    this.values=values;
                }else{
                    this.values[index]=new String[] {header, value};
                }
            }
           
            public File getFile(File dir){
                File f = new File(dir, name);
                if(!f.exists())
                    try {
                        f.createNewFile();
                        save(dir);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                return f;
            }
           
            public String[][] load(File dir){
                values = FileSQL.load(getFile(dir));
                if(values == null)values = new String[0][0];
                return values;
            }
           
            public void save(File dir){
                FileSQL.save(values, getFile(dir));
            }
           
        }
       
        public static void save(Object map, File f) {
            try
            {
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
                oos.writeObject(map);
                oos.flush();
                oos.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
       
        @SuppressWarnings("unchecked")
        public static <T extends Object>T  load(File f){
            try {
                FileInputStream fis = new FileInputStream(f);
                ObjectInputStream ois = new ObjectInputStream(fis);
                Object result = null;
                if(fis.available() > 0)result = ois.readObject();
                ois.close();
                return (T) result;
            } catch (EOFException e) {
                return null;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
       
    }
    
    so... how do i use it?

    FileSQL is made to be very simple to use, in the code above it only allows you to save strings although this can easily be changed to other values and if wanted i will change the code above.

    Creating a FileSQL "Server"(Folder where all values are kept)
    creating a filesql "server" is very simple, simply create a new instance of FileSQL in your plugin. To create an instance of FileSQL it will take a file object called dir, this is where all the values will be stored. I suggest creating a new folder for this as it will create many files. Note, you do not actually have to physically create the folder, it will create it for you, you just have to put in the directory you want it to be put.

    example:
    Code:
    FileSQL file = new FileSQL(new File("/root/filesql/"));
    Getting a Value
    We can now use our recently created file object to get a value. Each value requires a name, this can be, for example, a players name.

    example:
    Code:
    Value value = file.getValue("sothatsit");
    "sothatsit" is my username, but this can be whatever you want.

    Setting/Retrieving Values
    With this you can now set values. each value requires a "header" which is used as a sort of variable name so you can easily find the values after loading them.

    example:
    Code:
    value.setValue("points", "5");
    this is an example of a use of this, you could use this as a cross-server points system and then have a value called "points" for each player.

    Before you can retrieve the file you must load the values from the file, note that this will automatically load the file for you when you use the FileSQL.getValue() method but if you store the variable for a while you would want to load it again. To load the file we just need to use the Value.load(File dir) method.

    example:
    Code:
    value.load(file.getDir());
    as you can tell this method requires a file dir. this is where the file system is located. this will be the same as you used when initialising your FileSQL object so we can just use file.getDir() to get it.

    To retrieve the value after saving just use the header again, in this example "points".

    example:
    Code:
    String points = value.getValue("points");
    Saving Values
    After setting the values you will want to save them so the other server can access the newly updated files. This is farely simple.

    example:
    Code:
    value.save(file.getDir());
    the Value.save() function requires a file argument. this is the same as the one we used at the start when we initialised FileSQL, so we can just get this from that again using file.getDir().

    Some more Methods
    atm, there are not many methods other than what are required but i may add more in the future. One method you may want is the Value.getFile() method. This method also takes the directory of your "server" which again can be retrieved using file.getDir(). This method simply returns the File of the specific value.

    as i have been writing this i have realised that this could be used as a saving system for other plugins by simply setting the filesql's "server" directory to one in the plugins folder.

    all contributions and feedback to this is greatly appreciated! If you use this, a simple "This plugin uses FileSQL by sothatsit" would be nice although not necessary. I would also like to see any plugins that use this, so please post below.
     
  2. Offline

    user_43347

    If anything, you made it less efficient. One file for each value is just asking for trouble, especially if another server is reading/writing to the same files and the read/write speeds of your HDD could literally make or break this. And what do you mean "then taking time sending requests to a mysql server"? Because MySQL will run so many times faster then this, it also has a queue and works with multiple connections. This would have servers fighting over file read/write.

    You also read the file every single time they want to get the value instead of just storing it...
     
  3. Offline

    Ultimate_n00b

    For a second I thought you modified the quote.. then I realized you didn't.
     
  4. Offline

    user_43347

    I wish I would've needed to :p
     
  5. I have seen plugins breaking in the past because the files got readed by 1 thread (or another process) while being written by another thread (or process), this mainly happens when there are a bunch of read and write calls, Ever heard from thread concurrency?
     
Thread Status:
Not open for further replies.

Share This Page