0

I have written this code for reading a file from class path, now I want to write inside the same file inside class path. Please tell how I can do that?

import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JOptionPane;



public class A {

    public A() throws Exception {

        final InputStream inputStream = A.class.getResourceAsStream("f/file.txt");
        final InputStreamReader r = new InputStreamReader(inputStream);

        int end;
        String out="";

        while((end=r.read())!=-1)
            out+=(char)end;

        JOptionPane.showMessageDialog(null, out);
    }

    public static void main(String arg[] ) throws Exception {
        new A();
    }
}
user3787543
  • 11
  • 1
  • 3

3 Answers3

1

It won't work if the file you're trying to write to is in a JAR, but, in general, you can retrieve the resource's URL and then use that to write to it.

URL url = A.class.getResource("f/file.txt");
File f = new File(url.toURI().getPath());

// binary data
FileOutputStream fos = new FileOutputStream(f);
fos.write( /* data */ );
fos.close();

// OR text
FileWriter fw = new FileWriter(f.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write( /* data */ );
bw.close();

Remember to be careful, though, that the file can actually be written to.

Computerish
  • 9,590
  • 7
  • 38
  • 49
  • I am making a simple game in which I want to save the scores of players, how I can do that? – user3787543 Jun 29 '14 at 13:38
  • You can read and write to other files without a problem. The class path risk is just that your game might get packaged up in a JAR file and then you'd be trying to write to a file within the JAR. See here for general Java file IO: http://stackoverflow.com/questions/2885173/java-how-to-create-and-write-to-a-file – Computerish Jun 29 '14 at 13:46
0

If you want to record the players scores, you have to save it in a file (highscores.dat per example). In my way to see things, you can't record inside a .jar file because de system is using it.

And for the records, you can create a class that encaspulate the highscore of one game, and then you create an array that contains the totality of highscores.

class HighScoreRecord implements java.io.Serializable {

        private static final long serialVersionUID = 1L;

        private final String name;
        private final int highScore;

        HighScoreRecord( String name, int highScore ){
            this.name = name;
            this.highScore = highScore;
        }
}

Dont forget to implement java.io.Serializable, otherwise you won't be able to save it. And don't forget to create a private static field of long type "serialVersionUID" because the JVM can atribute its own serial if there is none and it can cause incompatibility with files already recorded.

HighScoreRecord[] highscores = new HighScoreRecord[]{ 
    new HighScoreRecord( "Player1", 1000 ), 
    new HighScoreRecord( "Player2", 800 ), 
    new HighScoreRecord( "Player3", 600 ), 
    new HighScoreRecord( "Player4", 400 ), 
    new HighScoreRecord( "Player5", 200 ) 
};

To save the records:

private void writeHighScores() {

    FileOutputStream fileOutput = null;
    ObjectOutputStream save = null;

    try {
        //HIGH_SCORES_FILE is any object of type File
        fileOutput = new FileOutputStream( HIGH_SCORES_FILE );
        save = new ObjectOutputStream( fileOutput );

        save.writeObject( highscores );
    }
    catch ( FileNotFoundException ex ) {
        //Exception handling
    }
    catch ( IOException ex ) {
        //Exception handling
    }
    finally {

        if( save != null )
            try{
                save.close();
            } catch ( IOException ex ) { 
                //Exception handling
            }

        if( fileOutput != null )
            try{
                fileOutput.close();
            } catch ( IOException ex ) { 
                //Exception handling
            }

    }
}

EDIT:

To load:

HighScoreRecord[] high = null;

        FileInputStream fileInput = null;
        ObjectInputStream load = null;

        try {

            fileInput = new FileInputStream( HIGH_SCORES_FILE );
            load = new ObjectInputStream( fileInput );

            high = (HighScoreRecord[]) load.readObject();
        }
        catch ( FileNotFoundException ex ) {
            //Exception handling
        }
        catch ( IOException | ClassNotFoundException ex ) {
            //Exception handling
        }
        finally {

            if( load != null )
                try{
                    load.close();
                } catch ( IOException ex ) { 
                    //Exception handling
                }

            if( fileInput != null )
                try{
                    fileInput.close();
                } catch ( IOException ex ) { 
                    //Exception handling
                }

        }

        highscores = high;

I hope I have helped.

saclyr
  • 161
  • 5
  • This code is creating the file outside the JAR, but I need to create the file inside the JAR. Is it possible or not? – user3787543 Jun 29 '14 at 16:57
  • I said it in other words, but what I meant is no, it is not possible. I'm sorry if could not help you. – saclyr Jun 29 '14 at 18:14
0

If your application classpath is pointing to a directory which you can write access to then once you create a file in that directory it will be available to load it as a resource.

If you don't have a directory in your classpath you can create a class loader which will be pointing to the directory.

Also if you are using Java 7 and above you should take advantage of the Path API as well as the try-with-resources language feature which would make you code smaller and less error prune.

Here is an example:

public class FileIO {

    public static void main(String[] args) throws IOException {
        Path tmpDir = Files.createTempDirectory("test");
        String string = "My data";
        Path file = tmpDir.resolve("myfile.txt");
        System.out.println("File created: " + file);

        Files.write(file, string.getBytes());

        String myString = new String(Files.readAllBytes(file));
        System.out.println("Read from file: " + myString);

        URLClassLoader classLoader = new URLClassLoader(new URL[]{tmpDir.toUri().toURL()});
        try (InputStream stream = classLoader.getResourceAsStream("myfile.txt");
             BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
            System.out.println("Read from class loader: " + reader.readLine());
        }
    }
}

Output:

File created: /var/folders/97/63hj35sn6wb0tmcnkrhf5b040000gn/T/test3343347264203608746/myfile.txt
Read from file: My data
Read from class loader: My data
Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48