Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我得到的数组索引超出了范围,但我可以';找不到原因是什么?_Java - Fatal编程技术网

Java 我得到的数组索引超出了范围,但我可以';找不到原因是什么?

Java 我得到的数组索引超出了范围,但我可以';找不到原因是什么?,java,Java,在这个类中,我只是处理一个二进制文件,但每次编译时,我都会得到一个数组索引,我需要做的就是增强这个代码,这样它就不用从文本文件读写,而是使用二进制文件,我的数组列表对我来说似乎很好?任何帮助都将不胜感激 import java.util.*; import java.io.*; import java.nio.file.*; public final class ProductBinaryFile implements ProductDAO { private ArrayList<

在这个类中,我只是处理一个二进制文件,但每次编译时,我都会得到一个数组索引,我需要做的就是增强这个代码,这样它就不用从文本文件读写,而是使用二进制文件,我的数组列表对我来说似乎很好?任何帮助都将不胜感激

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;
    }   
}
import java.util.*;
导入java.io.*;
导入java.nio.file.*;
公共最终类ProductBinaryFile实现ProductDAO
{
私有ArrayList产品=null;
私有路径productsPath=null;
私有文件productsFile=空;
私有最终字符串字段_SEP=“\t”;
公共产品二进制文件()
{
productsPath=path.get(“products.bin”);
productsFile=productsPath.toFile();
**products=this.getProducts()**
}
公共阵列列表getProducts()
{
//如果产品文件已被读取,请不要再次读取
if(产品!=null)
退货产品;
products=新的ArrayList();
if(Files.exists(productsPath))//防止FileNotFoundException
{
try(DataInputStream in=newdatainputstream(
新的BufferedInputStream(
新文件输入流(productsFile)))
{
//读取文件中存储的所有产品
//进入数组列表
String line=in.readUTF();
while(行!=null)
{
String[]columns=line.split(FIELD_SEP);
字符串代码=列[0];
**字符串说明=列[1]**
字符串价格=列[2];
产品p=新产品(
代码,描述,Double.parseDouble(price));
产品.加入(p);;
line=in.readUTF();
}
}
捕获(IOE异常)
{
系统输出打印ln(e);
返回null;
}
}
退货产品;
}
公共产品getProduct(字符串代码)
{
对于(产品p:产品)
{
if(p.getCode().equals(code))
返回p;
}
返回null;
}
公共布尔addProduct(产品p)
{
产品.加入(p);;
返回此.saveProducts();
}
公共布尔删除产品(产品p)
{
产品。去除(p);
返回此.saveProducts();
}
公共布尔更新产品(产品新产品)
{
//获取旧产品并将其移除
Product oldProduct=this.getProduct(newProduct.getCode());
int i=products.indexOf(旧产品);
产品。移除(i);
//添加更新的产品
产品。添加(i,新产品);
返回此.saveProducts();
}
私有布尔存储产品()
{        
try(DataOutputStream out=newdataoutputstream(
新的缓冲输出流(
新文件输出流(productsFile)))
{
//写入阵列列表中的所有产品
//归档
对于(产品p:产品)
{
out.writeUTF(p.getCode()+字段_SEP);
out.writeUTF(p.getDescription()+字段_SEP);
out.writeDouble(p.getPrice());
}
}
捕获(IOE异常)
{
系统输出打印ln(e);
返回false;
}
返回true;
}   
}
我试图读取的文本文件:

我认为您的错误在以下行之一:

String code = columns[0]; 
String description = columns[1]; 
String price = columns[2];
我的理论是,你所阅读的内容并没有你想象的那么长(也许tab是一个糟糕的分隔符选择);所以你只能得到一个条目或其他东西。获取列的长度并对其进行迭代(并打印元素),以确保它完全符合您的想法

编辑:
拆分的工作方式是,它接受字符串并根据分隔符(在本例中为:tab)将其分隔。如果没有标签,它的长度只有一个。如果输入包含两个选项卡,例如:“gdfb\tdrfb\trdb”,则其长度为3

第二次编辑: 如果您只读取标准文本文件,为什么不使用BufferedReader或Scanner? 例如:
Scanner fromFile=new Scanner(new FileReader(filename))

然后,您可以使用
nextLine()
获取整行,并将其拆分。

在下面的代码中,您的
列的数组长度似乎是1。因此,它无法访问[1]。它只能访问[0]

    String[] columns = line.split(FIELD_SEP);
    String code = columns[0];
    **String description = columns[1];**
通过执行系统输出,检查
列的长度
数组:

System.out.println("columns length : " + columns.length)
问题更新后更新答案:

BufferedReader in = new BufferedReader(new FileReader(productsFile));
in.readLine();
在您最近的评论和新的错误点**指向
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原语类型阅读):

BufferedReader in = new BufferedReader(new FileReader(productsFile));
in.readLine();
你阅读的方式和得到的结果是完美的。因为
readUTF
应该读取j