4

I'm learning Java from the Oracle documentation and lessons and I got to this part (file I/O, streams, etc) and I have some code here that just doesn't work, and I'm not sure why. I don't get any errors or warnings, nothing, the DataOutputStream simply won't write to the file.

I tried removing the BufferedOutputStream and it works that way, so I'm guessing that the problem lies on the Buffered Stream, but I don't know why.

Perhaps something is missing. I'm really stuck.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Principal {

    static final String dataFile = "invoicedata.txt";

    static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
    static final int[] units = { 12, 8, 13, 29, 50 };
    static final String[] descs = {
        "Java T-shirt",
        "Java Mug",
        "Duke Juggling Dolls",
        "Java Pin",
        "Java Key Chain"
    };

    public static void main(String[] args) throws IOException {     
        //DECLARATION
        DataOutputStream out = null;
        DataInputStream in = null;

        try {
            out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
            in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile)));

            //WRITING???
            for (int i = 0; i < prices.length; i ++) {
                out.writeDouble(prices[i]);
                out.writeInt(units[i]);
                out.writeUTF(descs[i]);
            }

        } catch (Exception e) {
            System.err.println("ERROR!");
            e.printStackTrace();
        }

        double price;
        int unit;
        String desc;
        double total = 0.0;

        //READING
        try {
            while (true) {
                price = in.readDouble();
                unit = in.readInt();
                desc = in.readUTF();
                System.out.format("You ordered %d" + " units of %s at $%.2f%n",
                    unit, desc, price);
                total += unit * price;
            }
        } catch (EOFException e) {
            System.err.println("END OF FILE!");
        }       
    }   
}
tckmn
  • 57,719
  • 27
  • 114
  • 156
Gabriel Matusevich
  • 3,835
  • 10
  • 39
  • 58

6 Answers6

1

You forget to call close() on your out.

    try {
        out = new DataOutputStream(new FileOutputStream(dataFile));
        in = new DataInputStream(new FileInputStream(dataFile));

        //WRITING???
        for (int i = 0; i < prices.length; i ++) {
            out.writeDouble(prices[i]);
            out.writeInt(units[i]);
            out.writeUTF(descs[i]);
        }
        out.close();
    } catch (Exception e) {
        System.err.println("ERROR!");
        e.printStackTrace();
    }

You should also close your in.

Sinister Beard
  • 3,570
  • 12
  • 59
  • 95
MrSmith42
  • 9,961
  • 6
  • 38
  • 49
1

If you don't close() the file, the end of the file can be truncated. If the file is small enough this can mean it will be empty.

If you use custom objects instead of arrays the code might look like this

public static void main(String... ignored) throws IOException {
    List<Inventory> inventories = new ArrayList<>();
    inventories.add(new Inventory("Java T-shirt", 19.99, 12));
    inventories.add(new Inventory("Java Mug", 9.99, 8));

    String dataFile = "invoice-data.dat";
    DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
    out.writeInt(inventories.size());
    for (Inventory inventory : inventories)
        inventory.write(out);
    out.close();

    DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile)));
    int count = in.readInt();
    for (int i = 0; i < count; i++) {
        System.out.println(new Inventory(in));
    }
    in.close();
}

static class Inventory {
    final String name;
    final double price;
    int units;

    Inventory(String name, double price, int units) {
        this.name = name;
        this.price = price;
        this.units = units;
    }

    Inventory(DataInput in) throws IOException {
        this.name = in.readUTF();
        this.price = in.readDouble();
        this.units = in.readInt();
    }

    public void write(DataOutput out) throws IOException {
        out.writeUTF(name);
        out.writeDouble(price);
        out.writeInt(units);
    }

    @Override
    public String toString() {
        return "name='" + name + '\'' +
                ", price=" + price +
                ", units=" + units;
    }
}

prints

name='Java T-shirt', price=19.99, units=12
name='Java Mug', price=9.99, units=8
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • OOohh. Right.. completly forgot about closing... i'll try that just now thank you – Gabriel Matusevich Jan 09 '13 at 13:54
  • @GabrielMatusevich I have added a suggestion of how you could make it moer object oriented to make the main method cleaner. – Peter Lawrey Jan 09 '13 at 13:57
  • awesome! that was just an Oraclae Example :3 ... but that was really helpfull :) – Gabriel Matusevich Jan 10 '13 at 11:57
  • I Have an OFF-TOPIC Question!, But You seem to really know ur Java :3 – Gabriel Matusevich Jan 10 '13 at 11:59
  • If you look at my profile, you can email me a question if it doesn't suit this forum. – Peter Lawrey Jan 10 '13 at 12:00
  • What do you consider to be a LARGE OBJECT... i've seen many examples where it says: "This method is inneficient when passing LARGE OBJECTS"... but there is no example of HOW Complex IS a Large Object, How much fields, Variable Size... Etc... if You could share more knowledge with me.. great :D – Gabriel Matusevich Jan 10 '13 at 12:01
  • Cool.. ill write it down :v – Gabriel Matusevich Jan 10 '13 at 12:02
  • When I see words like "large", "huge", "fast" it usually entirely subjective and not by a small amount, it can vary by one thousand to one million times or even more. What I might consider huge or fast is usually completely different. ;) I have seen posters describe "entirely significant" memory usage which equates to a few *millionths* of a cent of memory. – Peter Lawrey Jan 10 '13 at 12:09
  • I interviewed at one place where they had a multi-national data system which has "huge" and "high performance". The load they were handling across thousands of servers in a day I was used to handling on one PC in less than a minute. – Peter Lawrey Jan 10 '13 at 12:12
  • That's probably a reason why they dont actually describe it in the documentation,, it depens also in the current hardware you are using :) ... – Gabriel Matusevich Jan 10 '13 at 14:05
  • But thank You for the insight – Gabriel Matusevich Jan 10 '13 at 14:06
  • A common misconception is that large business problem means you have an equally large technical problem. e.g. server(s) which are large as well. I worked at one large company with a large number of employees in many countries (65K) They wanted to create an LDAP directory and I suggested redundant masters with replication to local sites and they considered this could never work because it had to be large!? The fact an LDAP database can handle 10 million entires easily was lost on them. – Peter Lawrey Jan 10 '13 at 14:14
  • Taking that into consideration, do you know of some Software to measure the Performance or the Use of Resources of a Solution????? – Gabriel Matusevich Jan 10 '13 at 15:55
  • I use a system tools like `top` and `iostat` and tune using a CPU+Memory profiler – Peter Lawrey Jan 10 '13 at 16:04
1

You need to add out.close() to your code to close the DataOutputStream after all the things have been written to the file.

Deepak kumar Jha
  • 524
  • 5
  • 16
0

Add this to the end of the writing part:

    out.close();

And this to the end of the reading part;

    in.close();
tckmn
  • 57,719
  • 27
  • 114
  • 156
0

When the process terminates the unmanaged resources will be released. For InputStreams this is fine. For OutputStreams, you could lose an buffered data, so you should

flush() or close()

the stream before exiting the program.

Achintya Jha
  • 12,735
  • 2
  • 27
  • 39
0

It can also happen that you want to write to / read from a closed stream. Java won't notify you at all, no error, no message, nothing. So, make sure that you write to / read from an open stream.

ady
  • 1,108
  • 13
  • 19