コードにいくつかの問題があります。
あなたの方法を最初に見てくださいreadFromFile:
- メソッドが見つけたすべてのレコードで埋めている配列を渡しています。配列内のスペースよりも多くの顧客がファイル内にある場合はどうなりますか? (ヒント:
ArrayIndexOutOfBoundsException物です) 
- ファイルから文字列として読み取った整数を解析しています。ファイルが壊れていて、読み取った行が整数でない場合はどうなりますか?
 
- 読み取るファイルの名前はハードコーディングされています。これは、定数または構成オプションである必要があります。メソッドを書く目的では、それをパラメーターにするのが最善です。
 
- ファイルを開き、メソッドで読み取ります。単体テストのために、これを別々のメソッドに分割する必要があります。
 
Collections一般に、オブジェクトのリストを保持するには、配列ではなくクラスを使用する必要があります。 
Customerメソッドで属性に直接アクセスしていますreadFromFile。アクセサーメソッドを使用する必要があります。 
Collectionsに基づくアプローチ
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;
}
これは、このメソッドを使用して実際にコンテンツを読み取ります。
public static List<Customer> readFromStream(BufferedReader br) throws IOException {
    List<Customer> customerList = new LinkedList<>();
    // 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;
}
に対して同様のアプローチを使用するとwriteToFile、次のようになります。
static void writeToFile(Collection<Customer> customers, String filename) throws IOException {
    // set up file for output
    // pw used to write to file
    File outputFile = new File(filename);
    FileOutputStream fos = new FileOutputStream(outputFile);
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
    writeToStream(customers, pw);
    pw.flush();
    pw.close();
}
static void writeToStream(Collection<Customer> customers, PrintWriter pw) throws IOException {
    for (Customer customer: customers) {
        pw.println(customer.getName());
        pw.println(customer.getNumber());
    }
    pw.println(0);
    pw.println(0);
}
しかし、私たちはあなたの主な懸念事項にまだ対処していません。を呼び出すときに、メモリ内の顧客とファイルの内容をマージしたいようです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);
}
ああ...私はほとんど忘れていました:ファイルとメモリ内リストをマージするために a を使用する魔法は、クラスにメソッドSetを実装することに依存しています。上書きする場合は、 も上書きする必要があります。例えば:equals()Customerequals()hashCode()
public class Customer {
    @Override
    public boolean equals(Object obj) {
        return (obj != null) && (obj instanceof Customer) && (getNumber() == ((Customer)obj).getNumber());
    }
    @Override
    public int hashCode() {
        return getNumber()+31;
    }
};
CustomerListに基づくアプローチ
APIを使用できない場合Collections、2 番目に良い方法は、同じ操作をサポートする独自のコレクション型を作成することですが、配列 (または、それを学習した場合はリンク リスト) によってサポートされます。あなたの場合、それは顧客のリストになります。タイプを呼び出しますCustomerList:
既存のコードを分析すると、addメソッドを実装するクラスと、リストをトラバースする方法が必要になります。を無視しIteratorsて、後者を agetLengthと a 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<Customer>ます。
static void writeToFile(CustomerList customers, String filename) throws IOException {
    // set up file for output
    // pw used to write to file
    File outputFile = new File(filename);
    FileOutputStream fos = new FileOutputStream(outputFile);
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
    writeToStream(customers, pw);
    pw.flush();
    pw.close();
}
writeToStreamも非常に似ていますが、 を使用していないため、Iterator手動でリストをトラバースする必要があります。
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);
}
同様にreadFromFile-- リストタイプを除いてほとんど同じです:
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;
}
も、readFromStream型を除いてほとんど同じです (で使用されるメソッドCustomerListは、で使用されるものと同じ署名を持っていますList<Customer>:
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;
}
最も異なる方法は です。重複がないことを保証syncToFileするSetタイプがないため、ファイルから顧客を挿入しようとするたびに手動で確認する必要があります。
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);
}
addここで注意すべきことは、新しい容量を取得するための追加のコンストラクターを用意することで操作を最適化できたということCustomerListですが、少なくとも何かを理解するために残しておきます;)