4

我正在从 Oracle 文档和课程中学习 Java,我到了这一部分(文件 I/O、流等),我这里有一些代码不起作用,我不知道为什么。我没有收到任何错误或警告,什么也没有,DataOutputStream根本不会写入文件。

我尝试删除它BufferedOutputStream并且它以这种方式工作,所以我猜测问题出在缓冲流上,但我不知道为什么。

也许缺少了什么。我真的被困住了。

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!");
        }       
    }   
}
4

6 回答 6

1

您需要在代码中添加 out.close() 以在所有内容都写入文件后关闭 DataOutputStream。

于 2013-01-09T13:54:31.907 回答
1

您忘记调用close()您的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();
    }

您还应该关闭您的in.

于 2013-01-09T13:48:52.290 回答
1

如果你不关闭()文件,文件的结尾可能会被截断。如果文件足够小,这可能意味着它将是空的。

如果您使用自定义对象而不是数组,则代码可能如下所示

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;
    }
}

印刷

name='Java T-shirt', price=19.99, units=12
name='Java Mug', price=9.99, units=8
于 2013-01-09T13:49:11.930 回答
0

当进程终止时,非托管资源将被释放。对于 InputStreams 这很好。对于 OutputStreams,您可能会丢失缓冲数据,因此您应该

冲洗()或关闭()

退出程序之前的流。

于 2013-01-09T13:49:44.897 回答
0

将其添加到写作部分的末尾:

    out.close();

这到阅读部分的结尾;

    in.close();
于 2013-01-09T13:49:07.630 回答
0

也可能发生您想要写入/读取封闭流的情况。Java 根本不会通知您,没有错误,没有消息,什么都没有。因此,请确保您写入/读取打开的流。

于 2016-04-30T16:39:10.400 回答