2016-03-19 14 views
1

Bu kodlarda neyin yanlış olduğunu anlayamıyorum. Kaydedilen dosyanın üzerine yazılması ve yükün mevcut verileri yüklememesi. . Bu kod için aramış ama insanlar farklı kodları gibi görünüyor .. ben Sen koduyla bir takım konularda var benim baş ağrısıjava'da çalışıp çalışmaya devam etmeden yükleyemiyorum

// 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; 
} 
+1

tam olarak ne yanlış? Dosya kendisine kayıtlı bir NAME0 ve number0 varsa sen isim2 yazıp sayı2 ilk değerler silinecek ve ikinci değerler olacak ozaman: İlk kod verisi bunun yani mevcut üzerine – dovetalk

+0

sorunun Açıklamanız oldukça muğlak ben size açıktır umut .. o üzerine yazmak yoksa zaten kaydedilmiş değerleri okumuyor ikinci kodu gibi ...... yer almak – jill

+0

Yani 'writeToFile' birleştirmek istediğiniz dosya içeriğindeki kayıtlar geçti? – dovetalk

cevap

1

son verilmesine yardım edin.

sizin readFromFile yöntemin ilk bakıyor: Eğer yöntem bulduğu tüm kayıtları doluyor dizideki geçiyoruz

  • . Dosyada dizideki yerlerden daha fazla müşteri varsa ne olur? (ipucu: ArrayIndexOutOfBoundsException bir şeydir)
  • Dosyadan bir dize olarak okunan bir tamsayı ayrışıyorsunuz. Dosya bozuksa ve okunan satır tam sayı değilse ne olur?
  • Okunacak dosyanın adı kodlanmış. Bu sabit veya konfigürasyon seçeneği olmalıdır. Yazma yöntemleri için, bir parametre yapmak en iyisidir.
  • Dosyayı açıyorsunuz ve yöntemde okuyorsunuz. Birim testi amaçları için, bunu ayrı yöntemlere bölmelisiniz.
  • Genel olarak, nesne listesini tutmak için bir dizi yerine Collections sınıfı kullanıyor olmalısınız.
  • Customer özniteliklerine doğrudan readFromFile yöntemine erişiyorsunuz. Bir erişimci yöntemi kullanmalısınız. Bir Kullanılması

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

    : aslında içeriğini okumak için bu bu yöntemi kullanan

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

    :

Collections tabanlı bir yaklaşım

İşte

Önerdiğim yeniden yazma Collections API'leri kullanarak dayanıyor writeToFile için benzer bir yaklaşım, biz olsun:

Bununla birlikte, asıl ilginizi hala ele almıyoruz. Dosya içeriğini, writeToFile numaralı telefonu aradığınızda bellekteki müşterilerle birleştirmek istediğiniz görülüyor. Bunun yerine bu amaçla yeni bir yöntem önermenizi öneriyorum. Bu varolan yöntemleri tutar basit:

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

... Oh neredeyse unuttum: dosyayı birleştirme ve bellek içi liste Customer sınıfında equals() yöntemini uygulamak için size güvenir bir Set kullanmanın büyü. equals()'un üzerine yazıyorsanız, hashCode()'un üzerine de yazmalısınız. Örneğin:

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 tabanlı bir yaklaşım

Eğer Collections API'leri, kullanamıyorsanız en iyi ikinci aynı işlemleri destekler, ancak bir dizi tarafından desteklenmektedir kendi koleksiyonu türünü yazmak olacaktır (ya da bağlantılı bir liste, eğer bunu öğrendiyseniz).Senin durumunda, müşterinin bir listesi olurdu. :

Mevcut kodu analiz ederek, bir add yöntemini uygulayan bir sınıfa ve listeyi geçmenin bir yoluna ihtiyacımız olacak. Iterators yok sayarak, bir getLength ve (dizine göre) bir getCustomer ile ikincisi başarmak gerekir. Senkronizasyon için, aynı zamanda bir müşteri listesinde olup olmadığını kontrol etmek için bir yol gerekir, bu yüzden contains yöntemi ekleyeceğiz: uygulanan Bununla

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 yöntemin yeniden yazma tam olarak aynı,

: writeToStream biz Iterator kullanmıyorsanız beri haricinde elle listesinde geçiş zorunda da çok benzer

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

: biz CustomerList yerine List<Customer> kullanmak dışında readFromFile benzer

- hemen hemen liste türü dışında aynı:

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 da hemen hemen aynı, CustomerList üzerinde kullanılan yöntemlerin (türü dışında olduğu aynı imza olarak bulunur olanlar List<Customer> kullanılan:

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

en farklı yöntem syncToFile, biz hiçbir çiftleri garanti Set türü yoktur, biz elle kontrol etmek zorunda Her zaman biz dosyasından bir müşteriyi eklemek deneyin: Yeni kapasite aldı CustomerList için ekstra yapıcısı alarak biz add operasyonlarını optimize olabilirdi burada dikkat edilmesi gereken

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

Something, ama ben bırakacağım En az için bir şey anlamayasınız;)

+0

teşekkür ederim Girişiniz için çok şey var… bu konuda mantıklı olabileceğiniz ve daha iyi anladığım bir yer olan java'ya gerçek bir anlayış sergiliyor.Set ile ilgili sorun, ben benim derste bu yana yoktu beri kullanamazsınız çünkü liste için \t kamu statik void list_of_customers (Müşteri c [], int number_of_customers göstermek için aşağıdaki kodu vardı) IOException \t a 0 =int m = 0; yapmak \t { \t c [m] .output(); \t m ++; \t} (m jill

+0

Yani tüm müşteriler için yeterli alana sahip olması garanti edilen geniş bir dizi vardı? Dizi yönetimini kapsüllemek için bir Müşteri Listesi oluşturmamanın bir nedeni var mı? – dovetalk

+0

Yanıtımı genişleterek, 'Koleksiyonlar' API'sini kullanmadan da aynısını nasıl yapabileceğinizi gösterdim. – dovetalk

1

Yazma yönteminizi düzeltmenin alternatif bir yolu da, bu dosyanın dosya sonuna eklenmesini isteyen bir FileOutputStream yapıcısı kullanmak olabilir.

FileOutputStream fos = new FileOutputStream(outputFile, true); 

Bu, hata koşullarında bile, her zaman bir satır sonu ile birlikte eksiksiz bir son kayıt yazdığınızı varsayar. Hala diğer solüsyonu (okuma ve birleştirme) ile bu tür durumlar ile uğraşmak gerekecek, ama bu bir ile daha sonraki çalışma algılayabilir ve gerekirse onunla başa. Bu yüzden tarif ettiğim append çözümü sağlam değil.

+0

Bu bir yaklaşım. Bununla birlikte, özel bir EOF 'Müşteri' işaretçisi kullandığımız gerçeğini görmezden gelir (isim ve rakam 0'a ayarlıdır. Elbette, bu işaretleyiciyi kullanmamak için orijinal yaklaşımı değiştirebiliriz ve bunun yerine EOF'yi kullanarak yerleşik Java dosyası G/Ç API'ları ... – dovetalk

İlgili konular