public void getFile(String fileName) throws RemoteException {

        HDFSFile file = null;
        try {
            file = this.nameNode.getFile(fileName);
        }
        catch (RemoteException e2) {
            e2.printStackTrace();
            System.out.println("[Error**] Exception occurs when fetching file " + fileName);
            return;
        }
        
        ConcurrentHashMap<Integer, HDFSChunk> chunkTable = file.getChunkTable();
        for (int i = 0; i < chunkTable.size(); i++) {

            HDFSChunk chunk = chunkTable.get(i);
            System.out.println("[LOG] Fetching chunk " + chunk.getChunkName() + " ...");
            byte[] buf = new byte[chunk.getChunkSize()];

            /** Try fetching data from at most 3 replicas in different dataNodes */
            for (DataNodeInfo dataNodeInfo : chunk.getReplicaDataNodes()) {
                try {
                    /* get dataNode RMI stub */
                    DataNodeInterface dataNode = getDataNodeService(dataNodeInfo.registryIP);
                    /* DataNode RMI call : readChunk(String fileName, int chunkNum) */
                    buf = dataNode.readChunk(fileName, i);
                    /* append data to local output file */
                    FileIO.appendFile(Common.LocalFSPath + fileName, buf);
                    /* go to next chunk */
                    break;
                }
                catch (IOException e) {
                    System.err.println("[Error**] Exception occurs when downloading file...");
                    try {
                        FileIO.deleteFile(Common.LocalFSPath + fileName);
                        return;
                    }
                    catch (IOException e1) {
                        System.err.println("[Error**] Cannot delete " + fileName);
                        return;
                    }
                }
                catch (NotBoundException e) {
                    continue;
                }
            }
        }
    }