保存到不在java中工作并从中加载

保存到不在java中工作并从中加载,java,methods,record,acm-java-libraries,Java,Methods,Record,Acm Java Libraries,就我个人而言,我不知道这些代码到底出了什么问题。。“保存以保持”会覆盖自身,而“加载自”不会加载已存在的数据。。我已经搜索了这个代码,但似乎人们使用不同的代码。。请帮我治好头痛 // Write to file static void writeToFile(Customer c[], int number_of_customers) throws IOException { // set up file for output // pw used to write to fil

就我个人而言,我不知道这些代码到底出了什么问题。。“保存以保持”会覆盖自身,而“加载自”不会加载已存在的数据。。我已经搜索了这个代码,但似乎人们使用不同的代码。。请帮我治好头痛

// Write to file
static void writeToFile(Customer c[], int number_of_customers) throws IOException {
    // set up file for output
    // pw used to write to file
    File outputFile = new File("Customers.dat");
    FileOutputStream fos = new FileOutputStream(outputFile);
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));

    int i = 0;
    do {
        pw.println(c[i].getName());
        pw.println(c[i].getNumber());
        i++;
    } while (i < number_of_customers);
    pw.println(0);
    pw.println(0);
    pw.close();
}

// Read from file
public static int readFromFile(Customer c[]) throws IOException {
    // set up file for reading
    // br used to read from file
    File inputFile = new File("Customers.dat");
    FileInputStream fis = new FileInputStream(inputFile);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

    String cus;
    int l = -1;
    // Subtract AND assignment operator, It subtracts right operand from the
    // left operand and assign the result to left operand
    int all_customers = 0;
    do {
        l++;
        c[l] = new Customer();
        c[l].cus_name = br.readLine();
        cus = br.readLine();
        c[l].cus_no = Integer.parseInt(cus);
        all_customers++;

    } while (c[l].cus_no != 0); // end while

    br.close(); // end ReadFile class
    return all_customers - 1;
}
//写入文件
静态void writeToFile(客户c[],客户的整数)引发IOException{
//设置输出文件
//用于写入文件的pw
File outputFile=新文件(“Customers.dat”);
FileOutputStream fos=新的FileOutputStream(outputFile);
PrintWriter pw=新的PrintWriter(新的OutputStreamWriter(fos));
int i=0;
做{
println(c[i].getName());
println(c[i].getNumber());
i++;
}而(i<客户数量);
pw.println(0);
pw.println(0);
关闭();
}
//从文件中读取
公共静态int readFromFile(客户c[])引发IOException{
//设置要读取的文件
//br用于从文件中读取
File inputFile=新文件(“Customers.dat”);
FileInputStream fis=新的FileInputStream(inputFile);
BufferedReader br=新的BufferedReader(新的InputStreamReader(fis));
字符串cus;
int l=-1;
//减法和赋值运算符,它从
//左操作数并将结果赋给左操作数
int all_客户=0;
做{
l++;
c[l]=新客户();
c[l].cus_name=br.readLine();
cus=br.readLine();
c[l].cus_no=Integer.parseInt(cus);
所有客户++;
}while(c[l].cus_no!=0);//结束while
br.close();//结束ReadFile类
返回所有_客户-1;
}

您的代码有很多问题

首先看一下您的
readFromFile
方法:

public class CustomerList {

    private static final int INITIAL_SIZE = 100;
    private static final int SIZE_INCREMENT = 100;

    // list of customers. We're keeping it packed, so there
    // should be no holes!
    private Customer[] customers = new Customer[INITIAL_SIZE];
    private int numberOfCustomers = 0;

    /**
     * Adds a new customer at end. Allows duplicates.
     * 
     * @param newCustomer the new customer to add
     * @return the updated number of customers in the list
     */
    public int add(Customer newCustomer) {

        if (numberOfCustomers == customers.length) {
            // the current array is full, make a new one with more headroom
            Customer[] newCustomerList = new Customer[customers.length+SIZE_INCREMENT];
            for (int i = 0; i < customers.length; i++) {
                newCustomerList[i] = customers[i];
            }
            // we will add the new customer at end!
            newCustomerList[numberOfCustomers] = newCustomer;

            // replace the customer list with the new one
            customers = newCustomerList;
        }
        else {
            customers[numberOfCustomers] = newCustomer;
        }

        // we've added a new customer!
        numberOfCustomers++;

        return numberOfCustomers;
    }

    /**
     * @return the number of customers in this list
     */
    public int getLength() {
        return numberOfCustomers;
    }

    /**
     * @param i the index of the customer to retrieve
     * @return Customer at index <code>i</code> of this list (zero-based).
     */
    public Customer getCustomer(int i) {
        //TODO: Add boundary check of i (0 <= i < numberOfCustomers)
        return customers[i];
    }

    /**
     * Check if a customer with the same number as the one given exists in this list
     * @param customer the customer to check for (will use customer.getNumber() to check against list)
     * @return <code>true</code> if the customer is found. <code>false</code> otherwise.
     */
    public boolean contains(Customer customer) {
        for (int i = 0; i < numberOfCustomers; i++) {
            if (customers[i].getNumber() == customer.getNumber()) {
                return true;
            }
        }
        // if we got here, it means we didn't find the customer
        return false;
    }

}
  • 您正在传入一个数组,您的方法正在用它找到的所有记录填充该数组。如果文件中的客户数量超过阵列中的存储空间,会发生什么情况?(提示:
    ArrayIndexOutOfBoundsException
    是一件事)
  • 您正在解析从文件中读取为字符串的整数。如果文件已损坏且读取的行不是整数,会发生什么情况
  • 要读取的文件名是硬编码的。这应该是一个常量或配置选项。为了编写方法,最好将其设置为参数
  • 您正在打开文件并在方法中读取它。为了单元测试的目的,您应该将其拆分为单独的方法
  • 通常,应该使用
    集合
    类而不是数组来保存对象列表
  • 您直接在
    readFromFile
    方法中访问
    Customer
    属性。您应该使用访问器方法
集合
基于 下面是我基于使用
Collections
api提出的重写:

public static List<Customer> readFromFile(String filename) throws IOException {
    // set up file for reading
    // br used to read from file
    File inputFile = new File(filename);
    FileInputStream fis = new FileInputStream(inputFile);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

    List<Customer> customers = readFromStream(br);

    br.close(); // end ReadFile class

    return customers;
}
然而,我们仍然没有解决您的主要问题。调用
writeToFile
时,似乎要将文件内容与内存中的客户合并。我建议您为此目的引入一种新方法。这使现有方法更简单:

static void syncToFile(Collection<Customer> customers, String filename) throws IOException {

    // get a list of existing customers
    List<Customer> customersInFile = readFromFile(filename);

    // use a set to merge
    Set<Customer> customersToWrite = new HashSet<>();

    // first add current in-memory cutomers
    customersToWrite.addAll(customers);

    // then add the ones from the file. Duplicates will be ignored
    customersToWrite.addAll(customersInFile);

    // then save the merged set
    writeToFile(customersToWrite, filename);
}
基于客户列表的方法 如果您不能使用
集合
API,那么第二种最好的方法是编写您自己的集合类型,该类型支持相同的操作,但由数组(或链表,如果您已经了解了这一点)支持。在您的情况下,它将是一个客户列表。我将调用类型
CustomerList

在分析现有代码时,我们需要一个实现
add
方法和遍历列表的方法的类。忽略
迭代器
,我们将使用
getLength
getCustomer
(按索引)来完成后者。对于同步,我们还需要一种方法来检查客户是否在列表中,因此我们将添加一个
contains
方法:

public class CustomerList {

    private static final int INITIAL_SIZE = 100;
    private static final int SIZE_INCREMENT = 100;

    // list of customers. We're keeping it packed, so there
    // should be no holes!
    private Customer[] customers = new Customer[INITIAL_SIZE];
    private int numberOfCustomers = 0;

    /**
     * Adds a new customer at end. Allows duplicates.
     * 
     * @param newCustomer the new customer to add
     * @return the updated number of customers in the list
     */
    public int add(Customer newCustomer) {

        if (numberOfCustomers == customers.length) {
            // the current array is full, make a new one with more headroom
            Customer[] newCustomerList = new Customer[customers.length+SIZE_INCREMENT];
            for (int i = 0; i < customers.length; i++) {
                newCustomerList[i] = customers[i];
            }
            // we will add the new customer at end!
            newCustomerList[numberOfCustomers] = newCustomer;

            // replace the customer list with the new one
            customers = newCustomerList;
        }
        else {
            customers[numberOfCustomers] = newCustomer;
        }

        // we've added a new customer!
        numberOfCustomers++;

        return numberOfCustomers;
    }

    /**
     * @return the number of customers in this list
     */
    public int getLength() {
        return numberOfCustomers;
    }

    /**
     * @param i the index of the customer to retrieve
     * @return Customer at index <code>i</code> of this list (zero-based).
     */
    public Customer getCustomer(int i) {
        //TODO: Add boundary check of i (0 <= i < numberOfCustomers)
        return customers[i];
    }

    /**
     * Check if a customer with the same number as the one given exists in this list
     * @param customer the customer to check for (will use customer.getNumber() to check against list)
     * @return <code>true</code> if the customer is found. <code>false</code> otherwise.
     */
    public boolean contains(Customer customer) {
        for (int i = 0; i < numberOfCustomers; i++) {
            if (customers[i].getNumber() == customer.getNumber()) {
                return true;
            }
        }
        // if we got here, it means we didn't find the customer
        return false;
    }

}
实现此功能后,重写
writeToFile
方法完全相同,只是我们使用
CustomerList
而不是
List

writeToStream
也非常相似,只是因为我们没有使用
迭代器,所以必须手动遍历列表:

static void writeToStream(CustomerList customers, PrintWriter pw) throws IOException {

    for (int i = 0; i < customers.getLength(); i++) {
        pw.println(customers.getCustomer(i).getName());
        pw.println(customers.getCustomer(i).getNumber());
    }
    pw.println(0);
    pw.println(0);

}
readFromStream
除了类型(在
CustomerList
上使用的方法与在
列表上使用的方法具有相同的签名)之外,也几乎相同:

最不同的方法是
同步文件
,因为我们没有保证无重复的
类型,每次尝试从文件中插入客户时,我们都必须手动检查:

static void syncToFile(CustomerList customers, String filename) throws IOException {

    // get a list of existing customers
    CustomerList customersInFile = readFromFile(filename);

    // use a set to merge
    CustomerList customersToWrite = new CustomerList();

    // first add current in-memory customers
    for (int i = 0; i < customers.getLength(); i++) {
        customersToWrite.add(customers.getCustomer(i));
    }

    // then add the ones from the file. But skip duplicates
    for (int i = 0; i < customersInFile.getLength(); i++) {
        if (!customersToWrite.contains(customersInFile.getCustomer(i))) {
            customersToWrite.add(customersInFile.getCustomer(i));
        }
    }

    // then save the merged set
    writeToFile(customersToWrite, filename);
}
static void syncToFile(CustomerList客户,字符串文件名)引发IOException{
//获取现有客户的列表
CustomerList customersInFile=readFromFile(文件名);
//使用集合进行合并
CustomerList CustomerToWrite=新CustomerList();
//首先添加当前内存中的客户
对于(int i=0;i

这里需要注意的是,我们可以通过为
CustomerList
添加一个额外的构造函数来优化
add
操作,该构造函数占用了新的容量,但我至少要留给您一些东西来解决;)

您的代码有很多问题

首先看一下您的
readFromFile
方法:

public class CustomerList {

    private static final int INITIAL_SIZE = 100;
    private static final int SIZE_INCREMENT = 100;

    // list of customers. We're keeping it packed, so there
    // should be no holes!
    private Customer[] customers = new Customer[INITIAL_SIZE];
    private int numberOfCustomers = 0;

    /**
     * Adds a new customer at end. Allows duplicates.
     * 
     * @param newCustomer the new customer to add
     * @return the updated number of customers in the list
     */
    public int add(Customer newCustomer) {

        if (numberOfCustomers == customers.length) {
            // the current array is full, make a new one with more headroom
            Customer[] newCustomerList = new Customer[customers.length+SIZE_INCREMENT];
            for (int i = 0; i < customers.length; i++) {
                newCustomerList[i] = customers[i];
            }
            // we will add the new customer at end!
            newCustomerList[numberOfCustomers] = newCustomer;

            // replace the customer list with the new one
            customers = newCustomerList;
        }
        else {
            customers[numberOfCustomers] = newCustomer;
        }

        // we've added a new customer!
        numberOfCustomers++;

        return numberOfCustomers;
    }

    /**
     * @return the number of customers in this list
     */
    public int getLength() {
        return numberOfCustomers;
    }

    /**
     * @param i the index of the customer to retrieve
     * @return Customer at index <code>i</code> of this list (zero-based).
     */
    public Customer getCustomer(int i) {
        //TODO: Add boundary check of i (0 <= i < numberOfCustomers)
        return customers[i];
    }

    /**
     * Check if a customer with the same number as the one given exists in this list
     * @param customer the customer to check for (will use customer.getNumber() to check against list)
     * @return <code>true</code> if the customer is found. <code>false</code> otherwise.
     */
    public boolean contains(Customer customer) {
        for (int i = 0; i < numberOfCustomers; i++) {
            if (customers[i].getNumber() == customer.getNumber()) {
                return true;
            }
        }
        // if we got here, it means we didn't find the customer
        return false;
    }

}
  • 您正在传入一个数组,您的方法正在用它找到的所有记录填充该数组。如果有更多的顾客怎么办
    static void writeToStream(CustomerList customers, PrintWriter pw) throws IOException {
    
        for (int i = 0; i < customers.getLength(); i++) {
            pw.println(customers.getCustomer(i).getName());
            pw.println(customers.getCustomer(i).getNumber());
        }
        pw.println(0);
        pw.println(0);
    
    }
    
    public static CustomerList readFromFile(String filename) throws IOException {
        // set up file for reading
        // br used to read from file
        File inputFile = new File(filename);
        FileInputStream fis = new FileInputStream(inputFile);
        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    
        CustomerList customers = readFromStream(br);
    
        br.close(); // end ReadFile class
    
        return customers;
    }
    
    public static CustomerList readFromStream(BufferedReader br) throws IOException {
    
        CustomerList customerList = new CustomerList();
    
        // Subtract AND assignment operator, It subtracts right operand from the
        // left operand and assign the result to left operand
        boolean moreCustomers = true;
        while (moreCustomers) {
            try {
                Customer customer = new Customer();
                customer.setName(br.readLine());
                String sCustNo = br.readLine();
                customer.setNumber(Integer.parseInt(sCustNo));
                if (customer.getNumber() == 0) {
                    moreCustomers = false;
                }
                else {
                    customerList.add(customer);
                }
            }
            catch (NumberFormatException x) {
                // happens if the line is not a number.
                // handle this somehow, e.g. by ignoring, logging, or stopping execution
                // for now, we just stop reading
                moreCustomers = false;
            }
        }
    
        return customerList;
    }
    
    static void syncToFile(CustomerList customers, String filename) throws IOException {
    
        // get a list of existing customers
        CustomerList customersInFile = readFromFile(filename);
    
        // use a set to merge
        CustomerList customersToWrite = new CustomerList();
    
        // first add current in-memory customers
        for (int i = 0; i < customers.getLength(); i++) {
            customersToWrite.add(customers.getCustomer(i));
        }
    
        // then add the ones from the file. But skip duplicates
        for (int i = 0; i < customersInFile.getLength(); i++) {
            if (!customersToWrite.contains(customersInFile.getCustomer(i))) {
                customersToWrite.add(customersInFile.getCustomer(i));
            }
        }
    
        // then save the merged set
        writeToFile(customersToWrite, filename);
    }
    
    FileOutputStream fos = new FileOutputStream(outputFile, true);