-4

In this class I am just working with a binary file but every time I compile I get an array index out of bounds all I needed to do was enhance this code so instead of it reading and writing from a text file it does it using binary, my array list seems to be fine to me? any help would be appreciated

import java.util.*;
import java.io.*;
import java.nio.file.*;

public final class ProductBinaryFile implements ProductDAO
{
    private ArrayList<Product> products = null;
    private Path productsPath = null;
    private File productsFile = null;

    private final String FIELD_SEP = "\t";

    public ProductBinaryFile()
    {
        productsPath = Paths.get("products.bin");
        productsFile = productsPath.toFile();
        **products = this.getProducts();**
    }

    public ArrayList<Product> getProducts()
    {
        // if the products file has already been read, don't read it again
        if (products != null)
            return products;        

        products = new ArrayList<>();        

        if (Files.exists(productsPath))  // prevent the FileNotFoundException
        {
            try (DataInputStream in = new DataInputStream(
                     new BufferedInputStream(
                     new FileInputStream(productsFile))))
            {
                // read all products stored in the file
                // into the array list
                String line = in.readUTF();
                while(line != null)
                {
                    String[] columns = line.split(FIELD_SEP);
                    String code = columns[0];
                    **String description = columns[1];**
                    String price = columns[2];

                    Product p = new Product(
                        code, description, Double.parseDouble(price));

                    products.add(p);

                    line = in.readUTF();                    
                }
            }
            catch(IOException e)
            {
                System.out.println(e);
                return null;
            }
        }
        return products;            
    }

    public Product getProduct(String code)
    {
        for (Product p : products)
        {
            if (p.getCode().equals(code))
                return p;
        }
        return null;
    }

    public boolean addProduct(Product p)
    {
        products.add(p);
        return this.saveProducts();
    }

    public boolean deleteProduct(Product p)
    {
        products.remove(p);
        return this.saveProducts();
    }

    public boolean updateProduct(Product newProduct)
    {
        // get the old product and remove it
        Product oldProduct = this.getProduct(newProduct.getCode());
        int i = products.indexOf(oldProduct);
        products.remove(i);

        // add the updated product
        products.add(i, newProduct);

        return this.saveProducts();
    }

    private boolean saveProducts()
    {        
        try (DataOutputStream out = new DataOutputStream(
                               new BufferedOutputStream(
                               new FileOutputStream(productsFile))))
        {

            // write all products in the array list
            // to the file
            for (Product p : products)
            {
                out.writeUTF(p.getCode() + FIELD_SEP);
                out.writeUTF(p.getDescription() + FIELD_SEP);
                out.writeDouble(p.getPrice());
            }
        }
        catch(IOException e)
        {
            System.out.println(e);
            return false;
        }

        return true;
    }   
}

my text file am trying to read from: enter image description here

4

2 回答 2

1

在下面的代码中,看起来您的columns数组长度为 1。因此,它无法访问 [1]。它只能访问 [0]

    String[] columns = line.split(FIELD_SEP);
    String code = columns[0];
    **String description = columns[1];**

columns通过执行系统输出检查数组的长度:

System.out.println("columns length : " + columns.length)

问题更新后更新的答案:

在您最近的评论和新的错误指向** 之后this.getProducts,我假设您的问题在于productFile内容。

做这个:

BufferedReader in = new BufferedReader(new FileReader(productsFile));
in.readLine();

你读它的方式不对。按照我的建议去做。然后在阅读该行后进行拆分。

注意: readUTF用于读取使用格式化UTF-8 编码的字符。这仅仅意味着它以java原始类型的形式读取数据。这样当你阅读时,你可以直接将它们转换回java原始类型。不推荐用于读取普通的 UTF-8 字符串。

注意: readUTF仅当您以java原始类型( writeUTF:)的形式编写时才应使用。以 java 原始类型的形式读/写

答案已更新(因为 OP 想将其读取为 java 原始类型):

您阅读和获得结果的方式非常好。因为readUTF应该读取java原始类型。这就是为什么您在变量中获取java(检查文本文件)的原因。line检查你的写作方式。我不知道为什么在直接读取 java 原始类型时要进行字符串拆分。您需要继续做readUTF并从中创建Product对象。

于 2013-05-08T01:00:15.320 回答
1

我想你的错误是在以下几行之一:

String code = columns[0]; 
String description = columns[1]; 
String price = columns[2];

我的理论是,您正在阅读的内容并不像您想象的那么长(也许制表符对于分隔符来说是一个糟糕的选择);所以你只会得到一个条目或其他东西。获取列的长度并遍历它(并打印元素)以确保它正是您认为的那样。

编辑: split 的工作方式是它获取您的字符串并根据您的分隔符将其分隔,在本例中为:tab。如果有零个制表符,它的长度只会为 1。如果输入包含两个选项卡,例如:“gdfb\tdrfb\trdb”,它将具有长度 3

第二次编辑:如果您只阅读标准文本文件,为什么不使用 BufferedReader 或 Scanner?例如:Scanner fromFile= new Scanner(new FileReader(filename)); 那么您可以使用nextLine()来获取整行并对其进行拆分。

于 2013-05-08T00:58:26.023 回答