복붙노트

[HADOOP] Java에서 HDFS 및 로컬 파일 읽기

HADOOP

Java에서 HDFS 및 로컬 파일 읽기

HDFS인지 로컬인지에 관계없이 파일 경로를 읽고 싶습니다. 현재 접두어 인 file : // 및 HDFS 경로에 접두사 hdfs : //가있는 로컬 경로를 전달하고 다음 코드를 작성합니다

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

여기에서 FileSystem의 API를 사용하여 파일을 읽습니다.

이보다 더 좋은 방법이 있다면 알려주시겠습니까?

해결법

  1. ==============================

    1.이게 말이 돼,

    이게 말이 돼,

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

    이런 식으로 가면 수표를 줄 필요가 없습니다. Path에서 FileSystem을 직접 가져온 다음 원하는대로하십시오.

  2. ==============================

    2.다음과 같은 방법으로 FileSystem을 얻을 수 있습니다.

    다음과 같은 방법으로 FileSystem을 얻을 수 있습니다.

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

    경로가 hdfs : // 또는 file : //로 시작하는지 판단 할 필요가 없습니다. 이 API가 작업을 수행합니다.

  3. ==============================

    3.HDFS 경로에서 해당 목록 파일 아래의 코드 스 니펫을 확인하십시오. 즉 hdfs : //로 시작하는 경로 문자열. Hadoop 구성과 로컬 경로를 제공 할 수 있으면 로컬 파일 시스템의 파일도 나열됩니다. file : //로 시작하는 경로 문자열.

    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
    
  4. from https://stackoverflow.com/questions/17072543/reading-hdfs-and-local-files-in-java by cc-by-sa and MIT license