2014-10-19 10 views
5

Il mio compito è programmare un file system usando oggetti cartella e oggetti file, quindi utilizzare un oggetto File System per gestire i due oggetti nello stesso albero. Il mio problema è che non riesco a capire come trattare i due oggetti come lo stesso.Estratto Java per trattare due oggetti come gli stessi in un albero

L'assegnazione dice "Potrebbe essere utile disporre di una classe astratta ereditata dal file e dalla cartella, in modo da poterli trattare allo stesso modo." Ma continuo a ricevere errori.

import java.util.*; 

public class FileSys { 

    private Node firstFolder; 

    public void newFolder(String loc) { 
     if (firstFolder == null) { // If there are no folders 
      Node folder = new Folder(loc); 
      firstFolder = folder; 
     } 
     else { // If there are folders 

      String s = loc; 
      String[] folders = s.split("\\\\"); // Each file/folder name is put into an array 

      boolean found; // Flag if found 

      Node current = firstFolder; //Sets the first folder to the current 
      int n = 0; 

      while (folders.length - 1 > n) { // To find the folder being added to 

       int i = 0; 
       found = false; // Resets flag 

       while (current.size > i) { // To search through the names of the folders 

        if (current.next[i].name.equalsIgnoreCase(folders[n])) { 
         current = current.next[i]; 
         found = true; // Raises flag 
         break; 
        } 

        i++; 
       } 

       if (!found) // incomplete. Add Exception. 
        System.out.println("ERROR"); 

       n++; 
      } 

      Node folder = new Folder(folders[folders.length - 1]); 
      current.next[current.size] = folder; 
     } 
    } 

    abstract class Node { 
     String name; 

     Node(String name) { 
      this.name = name; 
     } 
    } 



    private class File extends Node { 
     String data; 

     File(String nm, String data) { 
      super(nm); 
      this.data = data; 
     } 
    } 


    private class Folder extends Node { 
     private static final int ARRAYSIZE = 20; // default array size 

     private int size = 0; 
     private Node[] next = new Node[ARRAYSIZE]; 

     public Folder(String nm) { 
      super(nm); 
      next[0] = null; 
     } 
    } 

// Main method omitted 
} 

Apprezzo qualsiasi aiuto nella giusta direzione! Sento che è un errore estremamente semplice, ma non ho abbastanza esperienza con oggetti e abstract per sapere cosa c'è che non va. Ho provato a trasmettere, ma questo porta a più errori durante il runtime. Grazie!

Edit:

FileSys.java:55: error: cannot find symbol 
       while(current.size > i) 
          ^
    symbol: variable size 
    location: variable current of type FileSys.Node 
FileSys.java:57: error: cannot find symbol 
        if(current.next[i].name.equalsIgnoreCase(folders[n])) 
          ^
    symbol: variable next 
    location: variable current of type FileSys.Node 
FileSys.java:59: error: cannot find symbol 
         current = current.next[i]; 
             ^
    symbol: variable next 
    location: variable current of type FileSys.Node 
FileSys.java:76: error: cannot find symbol 
      current.next[current.size] = folder; 
       ^
    symbol: variable next 
    location: variable current of type FileSys.Node 
FileSys.java:76: error: cannot find symbol 
      current.next[current.size] = folder; 
           ^
    symbol: variable size 
    location: variable current of type FileSys.Node 
5 errors 
+0

Qual è esattamente il problema? – immibis

+0

Quali errori ottieni? La configurazione della tua classe ha senso. – ApproachingDarknessFish

+0

Non so come trattare due oggetti come uguali. Ho creato una classe Node astratta ma ogni volta che utilizzo Node folder = new Folder(); Non riesco a utilizzare nessuno dei dati che si trovano nell'oggetto Cartella, come next o size. – Bleu

risposta

0

Qui si sta facendo current.size e current.next. Entrambi size e next sono private nella classe Folder. Significa che non puoi accedervi utilizzando le istanze, sono private per la classe e devono essere utilizzate internamente dalla classe.

Così, al fine di accedere usarli getter definiti con public accesso specificatore nella classe qualcosa come

public int getSize() { 
    //return size; 
} 

Speranza, questo aiuta.

1

Quando si dichiara una variabile come classe, è possibile chiamarla solo con i metodi definiti per tale classe.

Node n = new Folder(); 
n.name; //Fine, all nodes have the name attribute 
n.next; //Not fine, nodes do not have a next attribute 

La soluzione è tipo colata. Digitare il cast è un modo per dire al compilatore: "So che questo oggetto sarà di questo tipo in fase di esecuzione".

Folder f = (Folder) n; //We are telling the compiler that n is a Folder 
f.next; //Fine, because folders have the next attribute 

C'è un ultimo problema: è necessario distinguere tra cartelle e file. Possiamo utilizzare l'istanza dell'operatore.

if(n instanceof Folder){ 
    doFolderStuff(); 
}else if (n instanceof File){ 
    doFileStuff() 
} 
+0

Grazie! Stavo usando il casting di tipo nei posti sbagliati prima. Mi sono reso conto principalmente di averlo usato quando si usano puntatori come "current = (Folder) current.children [i];" – Bleu

0

Per quanto riguarda l'organizzazione è interessato si consiglia di unificare i contratti oggetto a trovare simili:

public interface FSFilter{ 
    public boolean accept(FSNode node); 
} 

public interface FSNode { 
    public String getPath(); 
    public FSNode getParent(): 
    public Volume getVolume(); 
    public boolean isFile(); 
    public boolean isFolder(); 
    public boolean isVolume(); 
    public boolean exists(); 
    public boolean delete(); 
    public List<FSNode> getSubNodes(boolean recursive, int depth, FSFilter filter); 
    public int deleteSubNodes(boolean recursive, int depth, FSFilter filter); 
    public long getSize(boolean recursive, int depth, FSFilter filter); 
} 

I metodi di cui sopra con diverse combinazioni di parametri avrebbe fornito la maggior parte delle operazioni si può desiderare da un file albero del sistema. Per aggiungere funzioni specifiche a tipi specifici di oggetti File system, è possibile fornire implementazioni per ciascuno. Per esempio Volume classe può avere un metodo in più diskUsage(), e File classe può avere getInputStream() ecc

public class File implements FSNode { //... implementation...//} 

public class Folder implements FSNode { //... implementation...//} 

public class Volume implements FSNode { //... implementation...//} 

Poi, si consiglia di posizionare tutta la logica di utilità che si applica su tutti questi come una funzione statica senza stato, come elenco ricorsivo di file, cancellazione, creazione e modifiche. Poiché queste operazioni di solito gestiscono le chiamate del sistema operativo sottostante. Questi sarebbero equivalenti di comandi OS come ls, rm, mount ecc. Nel programma. Le suddette implementazioni chiamerebbero queste funzioni di utilità internamente.Inoltre, la maggior parte del codice del file system complesso sarebbe risiedere qui:

public final class FSUtil{ 
    public static List<FSNode> list(boolean recursive, int depth, FSFilter filter){//... logic...//} 
    public static long byteSize(FSNode node, boolean recursive, depth, FSFilter filter){//... logic...//} 
    public static boolean delete(FSNode node,boolean recursive, FSFilter filter){//... logic...//} 
    ... and more ... 
} 

Per avere un riferimento, è possibile guardare le implementazioni esistenti come apache.commons.io.

Problemi correlati