-1

I am trying to write the contents of an arraylist to a text file. I am partially able to do this with my newbie coding skills, however at the moment it only writes the first line out of 48 lines to the text file.

I would assume that this might be due to the fact that i do not have a loop anywhere in my code however, i am not entirely sure whether id need a while loop, or for loop and where exactly i would need to put it? Could this perhaps be also due to my readFile method using String(readAllBytes(get(filename))) as opposed to reading in line by line?

    public static void main(String... p) throws IOException {

        List<SensorInfo> readings = new ArrayList<>();

        String filedata = readFile("client-temp.txt");

        SensorInfo info = new SensorInfo(filedata);
        readings.add(info);

        String data = createStringFromInfo(readings);
        System.out.println("Lines: " + readings.size());
        writeFile("datastore.txt", data);
    }
}

writeFile

public static void writeFile(String filename, String content)
    {
        try
        {
            Files.write(get(filename), content.getBytes());
        } 
        catch (IOException e)
        {
            System.out.println("Error wiring file: " + e);
        }
    }

createStringFromInfo

public static String createStringFromInfo(List<SensorInfo> infoList)
    {
        String data = "";
        for (SensorInfo info : infoList)
        {
            data += info.asData();
        }
        return data;
    }

SensorInfo http://pastebin.com/9DDDGzwV

rr0102
  • 19
  • 5
  • 2
    What `writeFile` method? – MadProgrammer Dec 11 '14 at 01:34
  • writeFile("datastore", data); – rr0102 Dec 11 '14 at 01:35
  • `createStringFromInfo`? – MadProgrammer Dec 11 '14 at 01:39
  • please find my edits above @MadProgrammer – rr0102 Dec 11 '14 at 01:41
  • 1
    There is only one `SensorInfo` object in your `readings` `List`, so unless that one object contains all the lines you're expecting, I don't really see how it can write more ... – MadProgrammer Dec 11 '14 at 01:44
  • Might be useful to see the `SensorInfo` constructor which accepts a String as an argument. – adamdc78 Dec 11 '14 at 01:46
  • @MadProgrammer i understand what you are saying. Is there a way i can store all the lines in that one object? – rr0102 Dec 11 '14 at 01:47
  • @adamdc78 please find link to SensorInfo in my edits – rr0102 Dec 11 '14 at 01:49
  • You're splitting your entire input on `,` in the `SensorInfo(String data)` Constructor but only using the first four strings in the resulting array and discarding the rest in your `SensorInfo(String... parms)` Constructor. You could add a method which splits your input and then uses a for loop to instantiate a `SensorInfo` for each grouping of 4 Strings in the split (you'll need validation here and to increase your counter by 4 for each iteration). You would want to add this OUTSIDE of your `SensorInfo` class. – adamdc78 Dec 11 '14 at 01:58
  • Yes, but you'd need to change it so that it could not only store those lines, but could also provide some kind of access to them... – MadProgrammer Dec 11 '14 at 02:04
  • @adamdc78 just to reiterate what you've said, create a method which splits the input (which in this case would be "client-temp.txt") and then use a for loop that will create an instance of SensorInfo for each grouping of 4 strings? – rr0102 Dec 11 '14 at 02:04
  • @MadProgrammer what do you mean by access? – rr0102 Dec 11 '14 at 02:05
  • @rr0102 Correct. Constructors are for a single instance of your class, but you've got data to instantiate 12 SensorInfo in this case (48 lines). Your `String...` constructor is also NOT safe as you can pass in 0 or more Strings but it doesn't check that the number of Strings passed is at least 4, so you will likely get `ArrayIndexOutOfBounds` exceptions with corrupt or partial data. – adamdc78 Dec 11 '14 at 02:08
  • @rr0102 The `SensorInfo` would (presumably) contain a `List` of the rows of data, you need to provide interested parties some way to gain access to it (like getter of some kind) – MadProgrammer Dec 11 '14 at 02:10

1 Answers1

0

MadProgrammer is right.
If I got it right, the file client-temp.txt has multiple lines; each one representing data from a single SensorInfo object. When you read all of them into filedata and pass it as a parameter for the constructor of SensorInfo, only the first line will be used to instantiate a single SensorInfo object, as you can clearly see from the source in the link you posted. All the remaining lines will be discarded. Keep in mind that a constructor of a class will always instantiate a single object of that class.
To resolve the issue you should read line by line from the file client-temp.txt and pass each one as a parameter for the creation of a new SensorInfo object that will be added to the list.

Here is a suggestion for your new main method:

public static void main(String[] args) {
    List<SensorInfo> readings = new ArrayList<>();

    try (BufferedReader br = new BufferedReader(new FileReader("client-temp.txt"))) {
        String line = br.readLine();

        while (line != null) {
            readings.add(new SensorInfo(line));
            line = br.readLine();
        }
    } catch (IOException e) {
        System.out.println("Unable to read data file");
        e.printStackTrace();
        System.exit(1);
    }

    String data = createStringFromInfo(readings);
    System.out.println("Lines: " + readings.size());
    writeFile("datastore.txt", data);
}

Regards

ulix
  • 999
  • 9
  • 13
  • in terms of reading the file, would you recommended that i change from using readAllBytes to BufferedReader where i can then read line by line? – rr0102 Dec 11 '14 at 02:27
  • Just added some reference code. I am assuming you are using at least java 1.7 otherwise the try-with-resources construction wont work. Let me know... – ulix Dec 11 '14 at 07:30