0

So, I was wondering if it's possible to save values from an ArrayList to a file, such as "inputs.txt". I've seen a question similar to this: save changes (permanently) in an arraylist?, however that didn't work for me, so I'm wondering if I'm doing something wrong. Here are my files: Main.class

package noodlegaming.geniusbot.main;

import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import java.util.logging.Logger;

public class Main {

    public static Random rand = new Random();

    public static void readFileByLine(String fileName) {
        try {
            File file = new File(fileName);
            Scanner scanner = new Scanner(file);
            while (scanner.hasNext()) {
            SentencesToUse.appendToInputtedSentences(scanner.next().toString());
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    static File inputsFile = new File("inputs.txt");

    static PrintWriter printWriter = new PrintWriter(inputsFile);

    public static void main(String[] args) throws IOException, InterruptedException {

        if(!inputsFile.exists()) {
            inputsFile.createNewFile();
        }

        readFileByLine("inputs.txt");

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Hello, welcome to GeniusBot. Shortly, you will be speaking with a computer that learns from what you say.");
        System.out.println("Because of this circumstance, we ask that you do not type any curses, swear words, or anything otherwise considered inappropriate,");
        System.out.println("as it may come back to the light at a time you don't want it to.");
        System.out.println("Please note that your responses won't be saved if you close the program.");
        System.out.println("If you type printInputsSoFar, a list of all the stuff you've typed will be printed.");
        System.out.println("If you type printInputsLeft, the number of inputs you have left will be printed.");
        System.out.println("If you type clearInputs, the program will be closed and the inputs.txt file deleted, " +
            "\nand recreated upon startup.");
        System.out.println("Starting up GeniusBot.");
        Thread.sleep(3000);
        System.out.println("Hello! I am GeniusBot!");
        br.readLine();
        System.out.println("" + SentencesToUse.getBeginningSentence() + "");

        for (int i = 0; i < 25; i++) {
            String response = br.readLine();

            if (response.equals("printInputsSoFar")) {
                for (int j = 1; j < SentencesToUse.inputtedSentences.size();    j++) {
                    System.out.println(SentencesToUse.inputtedSentences.get(j));
                }
                i--;
            } else if (response.equals("printInputsLeft")) {
                int inputsLeft = 25 - i;
                System.out.println("You have " + inputsLeft + " inputs left.");
                i--;
            } else if (response.equals("clearInputs")) {
                printWriter.close();
                inputsFile.delete();
                Thread.currentThread().stop();
            } else {
                SentencesToUse.appendToInputtedSentences(response);
                printWriter.println(response);
                printWriter.flush();

                int inputtedSentence = Main.rand.nextInt(SentencesToUse.inputtedSentences.size());
                String inputtedSentenceToUse = SentencesToUse.inputtedSentences.get(inputtedSentence);
                System.out.println(inputtedSentenceToUse);
            }

            if (i == 24) {
                System.out.println("Well, it was nice meeting you, but I have to go. \nBye.");
                Thread.currentThread().stop();

                printWriter.close();
            }
        }
    }
}

SentencesToUse.class:

package noodlegaming.geniusbot.main;

java.util.ArrayList;
import java.util.List;

public class SentencesToUse {

    public static String[] beginningSentences = {"What a lovely day!", "How are you?", "What's your name?"};

    static int beginningSentence = Main.rand.nextInt(beginningSentences.length);
    static String beginningSentenceToUse = beginningSentences[beginningSentence];

    public static String getBeginningSentence() {
        return beginningSentenceToUse;
    }

    public static List<String> inputtedSentences = new ArrayList<String>();

    public static void appendToInputtedSentences(String string) {
        inputtedSentences.add(string);
    }

    public static void clearInputtedSentences() {
        inputtedSentences.clear();
    }

}
Community
  • 1
  • 1
  • I think you will have much better luck writing the VALUES to the file, rather than the arraylist itself. Then, when you read them back, add them into the arraylist one by one (in a loop). – Russell Uhl Mar 23 '15 at 15:37
  • Would that be sort of like for(int i = 0; i < SentencesToUse.inputtedSentences.size(); i++) { oos.writeObject(SentencesToUse.inputtedSentences.get(i)); } ? –  Mar 23 '15 at 15:39
  • You'll want to use a `PrintWriter` (I think) and write a string, rather than an ObjectOutputStream and write an object, but yes, that seems more or less correct. http://stackoverflow.com/questions/11496700/how-to-use-printwriter-and-file-classes-in-java – Russell Uhl Mar 23 '15 at 15:43
  • @RussellUhl But then how would I read from that? –  Mar 23 '15 at 15:58
  • use a `Scanner`. The scanner would link to a File, just as the PrintWriter does: http://stackoverflow.com/questions/20311266/read-line-with-scanner – Russell Uhl Mar 23 '15 at 16:03
  • @RussellUhl PrintWriter is not working in the slightest. It won't print to the txt file no matter what I do. –  Mar 24 '15 at 00:44
  • Hmm. It's been a while since I've played with java, but I could have sworn that's how I did it. I'll try to see if I can figure out what's going on. In the meantime, did you remember to `flush()` your PrintWriter? – Russell Uhl Mar 24 '15 at 11:51

1 Answers1

0

As stated in the comments, use a PrintWriter to write the values to a file instead:

PrintWriter pw = new PrintWriter(fos);
for (int i = 0; i < SentencesToUse.inputtedSentences.size(); i++) {
    pw.write(SentencesToUse.inputtedSentences.get(i)+"\n"); // note the newline here
}
pw.flush(); // make sure everything in the buffer actually gets written.

And then, to read them back again:

try {
    Scanner sc = new Scanner(f);

    while (sc.hasNext()) {
        SentencesToUse.inputtedSentences.ass(sc.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

The pw.flush(); is incredibly important. When I was first learning java, I can't tell you how many hours I spent debugging because I didn't flush my streams. Note also the "\n". This ensures that there will be a newline, and that your sentences don't just run together in one giant blob. If each one already has a newline, then that's not necessary. Unlike print vs println, there is no writeln. You must manually specify the newline character.

Russell Uhl
  • 3,755
  • 2
  • 16
  • 27
  • Thank you very much. I have figured out a system that reads, but pw.flush() may be what I was missing when it comes to writing. Thanks! –  Mar 25 '15 at 01:34
  • As a bit of a side thing, I'd like to know if there's any way of me being able to delete a file without using `file.delete()` or `file.deleteOnExit()`, because there doesn't seem to be a way to clear files of their content, so I thought deleting and then recreating them might be better. However, `file.delete()` and `file.deleteOnExit()` aren't working in the slightest. –  Mar 25 '15 at 03:12
  • @TheAustralianBirdEatingLouse what's not working about it? are you getting an exception? Make sure you CAN delete it first (there's some method that checks...maybe `file.CanDelete()`? Something like that. If your program is creating the file, though, it should be able to delete it. Make sure you `close()` all of your streams (especially the printwriter and scanner) before you try to delete the file. – Russell Uhl Mar 25 '15 at 11:56
  • That worked, but the problem now is that my program is recreating the file every time it starts up. Do you know of any fix for this? I'm pretty sure it's a problem with the if() that determines whether or not the file exists, but I can't be sure. –  Mar 27 '15 at 03:14
  • try `.write()` or `.append()`: http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html – Russell Uhl Mar 27 '15 at 13:04
  • I fixed some stuff, and now the PrintWriter is declared outside of `main()`. The problem is that now it's telling me "Unhandled exception: java.io.FileNotFoundException". I've all ways to fix this, like saying `public Main() throws FileNotFoundException {}` as a constructor, which doesn't fix it, and I've tried putting the declaration in a `try`, but that doesn't work. If I said `PrintWriter printWriter;` outside the `main()` and then said `printWriter = new PrintWriter(inputsFile);` inside `main()` it would give me the same problem. –  Mar 29 '15 at 16:03
  • The exception is telling you what the problem is. It can't find the file. If you're feeding it a full path, make sure the path is correct. Make sure you have write permissions on the folder (although I think that's a different exception). try/catch is good, but in the catch you should actually HANDLE the problem. Simply labeling your main with `throws Exception` is a VERY bad idea. – Russell Uhl Mar 30 '15 at 12:25