2013-06-12 4 views
14

Я хочу читать пути к файлам независимо от того, являются ли они HDFS или локальными. В настоящее время я прохожу локальные пути с файлом префикса: // и HDFS пути с префиксом HDFS: // и написать некоторый код, следующийЧтение HDFS и локальных файлов в Java

Configuration configuration = new Configuration(); 
FileSystem fileSystem = null; 
if (filePath.startsWith("hdfs://")) { 
    fileSystem = FileSystem.get(configuration); 
} else if (filePath.startsWith("file://")) { 
    fileSystem = FileSystem.getLocal(configuration).getRawFileSystem(); 
} 

Отсюда я использую API, файлсистемы прочитать файл.

Не могли бы вы сообщить мне, есть ли другой способ?

+0

Почему вы недовольны своим текущим методом? – Chaos

+0

Я не несчастлив сам по себе. Я хочу, чтобы мой метод принимал объект Path, и мне было интересно с Path, если есть какой-либо метод, который может сказать мне, принадлежит ли этот путь локальной или файловой системе HDFS. Я попытался сделать toString пути и выполнить сравнение выше, но он не работал. Мне нужно toURI(). ToString() на пути и выполнить эту проверку. –

+0

Я не уверен, что мне нужно создать новое сообщение для этого. Прошу прощения, если бы у меня было. В качестве альтернативы, мой вопрос заключается в том, как найти путь к файлу HDFS или локальный, если у меня есть Path, а не String. Было бы нужно сделать toURI(). ToString() и сделать проверку, как я упоминал в своем первом сообщении. Или сделать toURI() и проверить, есть ли схема. Спасибо .... –

ответ

28

ли это имеет смысл,

public static void main(String[] args) throws IOException { 

    Configuration conf = new Configuration(); 
    conf.addResource(new Path("/hadoop/projects/hadoop-1.0.4/conf/core-site.xml")); 
    conf.addResource(new Path("/hadoop/projects/hadoop-1.0.4/conf/hdfs-site.xml")); 

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    System.out.println("Enter the file path..."); 
    String filePath = br.readLine(); 

    Path path = new Path(filePath); 
    FileSystem fs = path.getFileSystem(conf); 
    FSDataInputStream inputStream = fs.open(path); 
    System.out.println(inputStream.available()); 
    fs.close(); 
} 

Вы не должны поставить эту проверку, если идти по этому пути. Получите FileSystem прямо с Path, а затем сделайте все, что вам хочется.

+0

Хорошо работает Тарик. Спасибо за вашу помощь. –

+0

Добро пожаловать в Венк. Выглядит лучше после небольшого редактирования. – Tariq

+0

Привет, Tariq, может ли исходный локальный файл быть на граничном узле? у вас есть полный пример класса mapper? –

9

Вы можете получить FileSystem следующим образом:

Configuration conf = new Configuration(); 
Path path = new Path(stringPath); 
FileSystem fs = FileSystem.get(path.toUri(), conf); 

Вам не нужно судить, если путь начинается с hdfs:// или file://. Этот API выполнит эту работу.

+2

Решение Tariq делает то же самое. Path.getFileSystem вызовет этот метод FileSystem.get (URI, Configuration) –

0

Пожалуйста, проверьте фрагмент кода ниже этого списка файлов с пути HDFS; а именно строку пути, которая начинается с hdfs://. Если вы можете предоставить конфигурацию Hadoop и локальный путь, она также будет отображать файлы из локальной файловой системы; а именно строку пути, которая начинается с file://.

//helper method to get the list of files from the HDFS path 
    public static List<String> listFilesFromHDFSPath(Configuration hadoopConfiguration, String hdfsPath, 
                boolean recursive) 
    { 
     //resulting list of files 
     List<String> filePaths = new ArrayList<String>(); 
     FileSystem fs = null; 

     //try-catch-finally all possible exceptions 
     try 
     { 
      //get path from string and then the filesystem 
      Path path = new Path(hdfsPath); //throws IllegalArgumentException, all others will only throw IOException 
      fs = path.getFileSystem(hadoopConfiguration); 

      //resolve hdfsPath first to check whether the path exists => either a real directory or o real file 
      //resolvePath() returns fully-qualified variant of the path 
      path = fs.resolvePath(path); 


      //if recursive approach is requested 
      if (recursive) 
      { 
       //(heap issues with recursive approach) => using a queue 
       Queue<Path> fileQueue = new LinkedList<Path>(); 

       //add the obtained path to the queue 
       fileQueue.add(path); 

       //while the fileQueue is not empty 
       while (!fileQueue.isEmpty()) 
       { 
        //get the file path from queue 
        Path filePath = fileQueue.remove(); 

        //filePath refers to a file 
        if (fs.isFile(filePath)) 
        { 
         filePaths.add(filePath.toString()); 
        } 
        else //else filePath refers to a directory 
        { 
         //list paths in the directory and add to the queue 
         FileStatus[] fileStatuses = fs.listStatus(filePath); 
         for (FileStatus fileStatus : fileStatuses) 
         { 
          fileQueue.add(fileStatus.getPath()); 
         } // for 
        } // else 

       } // while 

      } // if 
      else  //non-recursive approach => no heap overhead 
      { 
       //if the given hdfsPath is actually directory 
       if (fs.isDirectory(path)) 
       { 
        FileStatus[] fileStatuses = fs.listStatus(path); 

        //loop all file statuses 
        for (FileStatus fileStatus : fileStatuses) 
        { 
         //if the given status is a file, then update the resulting list 
         if (fileStatus.isFile()) 
          filePaths.add(fileStatus.getPath().toString()); 
        } // for 
       } // if 
       else  //it is a file then 
       { 
        //return the one and only file path to the resulting list 
        filePaths.add(path.toString()); 
       } // else 

      } // else 

     } // try 
     catch(Exception ex) //will catch all exception including IOException and IllegalArgumentException 
     { 
      ex.printStackTrace(); 

      //if some problem occurs return an empty array list 
      return new ArrayList<String>(); 
     } // 
     finally 
     { 
      //close filesystem; not more operations 
      try 
      { 
       if(fs != null) 
        fs.close(); 
      } catch (IOException e) 
      { 
       e.printStackTrace(); 
      } // catch 

     } // finally 


     //return the resulting list; list can be empty if given path is an empty directory without files and sub-directories 
     return filePaths; 
    } // listFilesFromHDFSPath 

Если вы действительно хотите работать с java.io.File API, то следующий метод поможет вам список файлов только из локальной файловой системы; а именно строка пути, которая начинается с file://.

//helper method to list files from the local path in the local file system 
    public static List<String> listFilesFromLocalPath(String localPathString, boolean recursive) 
    { 
     //resulting list of files 
     List<String> localFilePaths = new ArrayList<String>(); 

     //get the Java file instance from local path string 
     File localPath = new File(localPathString); 


     //this case is possible if the given localPathString does not exit => which means neither file nor a directory 
     if(!localPath.exists()) 
     { 
      System.err.println("\n" + localPathString + " is neither a file nor a directory; please provide correct local path"); 

      //return with empty list 
      return new ArrayList<String>(); 
     } // if 


     //at this point localPath does exist in the file system => either as a directory or a file 


     //if recursive approach is requested 
     if (recursive) 
     { 
      //recursive approach => using a queue 
      Queue<File> fileQueue = new LinkedList<File>(); 

      //add the file in obtained path to the queue 
      fileQueue.add(localPath); 

      //while the fileQueue is not empty 
      while (!fileQueue.isEmpty()) 
      { 
       //get the file from queue 
       File file = fileQueue.remove(); 

       //file instance refers to a file 
       if (file.isFile()) 
       { 
        //update the list with file absolute path 
        localFilePaths.add(file.getAbsolutePath()); 
       } // if 
       else //else file instance refers to a directory 
       { 
        //list files in the directory and add to the queue 
        File[] listedFiles = file.listFiles(); 
        for (File listedFile : listedFiles) 
        { 
         fileQueue.add(listedFile); 
        } // for 
       } // else 

      } // while 
     } // if 
     else  //non-recursive approach 
     { 
      //if the given localPathString is actually a directory 
      if (localPath.isDirectory()) 
      { 
       File[] listedFiles = localPath.listFiles(); 

       //loop all listed files 
       for (File listedFile : listedFiles) 
       { 
        //if the given listedFile is actually a file, then update the resulting list 
        if (listedFile.isFile()) 
         localFilePaths.add(listedFile.getAbsolutePath()); 
       } // for 
      } // if 
      else  //it is a file then 
      { 
       //return the one and only file absolute path to the resulting list 
       localFilePaths.add(localPath.getAbsolutePath()); 
      } // else 
     } // else 


     //return the resulting list; list can be empty if given path is an empty directory without files and sub-directories 
     return localFilePaths; 
    } // listFilesFromLocalPath 
Смежные вопросы