hadop 2.6 소스 코드 판독 업로드 파일 (- put) 내부 구현 FsShell init () 편

hdfs 명령 행 - put 파일 업로드 작업, 셸 스 크 립 트 를 통 해 FsShell 의 main 입구 방법 을 최종 호출 하여 논리 적 기능 구현
debug 디 버 깅 에 편리 하도록 테스트 프로그램 시 뮬 레이 션 - put 작업 을 작성 합 니 다. 예제 코드 는 다음 과 같 습 니 다.
public class TestShell {

    public static void main(String argv[]) throws Exception {
        System.setProperty("hadoop.home.dir", "D:\\aws\\hadoop-2.6.0");
        System.setProperty("HADOOP_USER_NAME", "root");



        FsShell shell = new FsShell();
        Configuration conf = new Configuration();
        conf.setQuietMode(false);
        shell.setConf(conf);

        String[] args = {"-put","sdsd"};


        int res;
        try {
            res = ToolRunner.run(shell, args);
        } finally {
            shell.close();
        }
        System.exit(res);
    }

}

이 예제 코드 는 FsShell 류 의 main 방법 을 가 져 와 수정 한 ToolRunner. run () 에 뛰 어 들 었 습 니 다.
 public static int run(Tool tool, String[] args) 
    throws Exception{
    return run(tool.getConf(), tool, args);
  }

더욱 뛴다
  public static int run(Configuration conf, Tool tool, String[] args) 
    throws Exception{
    if(conf == null) {
      conf = new Configuration();
    }
    GenericOptionsParser parser = new GenericOptionsParser(conf, args);
    //set the configuration back, so that Tool can configure itself
    tool.setConf(conf);

    //get the args w/o generic hadoop args
    String[] toolArgs = parser.getRemainingArgs();
    return tool.run(toolArgs);
  }

tool. run (toolArgs), 이 코드 는 마지막 에 FsShell 류 의 run 으로 돌 아 왔 습 니 다.
@Override
  public int run(String argv[]) throws Exception {
    // initialize FsShell
    init();

    int exitCode = -1;
    if (argv.length < 1) {
      printUsage(System.err);
    } else {
      String cmd = argv[0];
      Command instance = null;
      try {
        instance = commandFactory.getInstance(cmd);
        if (instance == null) {
          throw new UnknownCommandException();
        }
        exitCode = instance.run(Arrays.copyOfRange(argv, 1, argv.length));
      } catch (IllegalArgumentException e) {
        displayError(cmd, e.getLocalizedMessage());
        if (instance != null) {
          printInstanceUsage(System.err, instance);
        }
      } catch (Exception e) {
        // instance.run catches IOE, so something is REALLY wrong if here
        LOG.debug("Error", e);
        displayError(cmd, "Fatal internal error");
        e.printStackTrace(System.err);
      }
    }
    return exitCode;
  }

매우 중요 한 init 방법 입 니 다. 이 안 은 매우 수 다스 럽 고 초기 화 작업 입 니 다.주로 해당 명령 행 파라미터 와 해당 처리 류 예제 의 맵 관 계 를 구축한다.독자
 protected void init() throws IOException {
    getConf().setQuietMode(true);
    if (commandFactory == null) {
      commandFactory = new CommandFactory(getConf());
      commandFactory.addObject(new Help(), "-help");
      commandFactory.addObject(new Usage(), "-usage");
      registerCommands(commandFactory);
    }
  }

가장 중요 한 것 은 register Commands (commandFactory) 입 니 다.
 protected void registerCommands(CommandFactory factory) {
    // TODO: DFSAdmin subclasses FsShell so need to protect the command
    // registration.  This class should morph into a base class for
    // commands, and then this method can be abstract
    if (this.getClass().equals(FsShell.class)) {
      factory.registerCommands(FsCommand.class);
    }
  }

factory. registerCommands () 로 이동
 public void registerCommands(Class> registrarClass) {
    try {
      registrarClass.getMethod(
          "registerCommands", CommandFactory.class
      ).invoke(null, this);
    } catch (Exception e) {
      throw new RuntimeException(StringUtils.stringifyException(e));
    }
  }

CommandFactory 방법 register Commands 의 디자인 방향 을 분석 하고,
  • registrarClass 에 전 달 된 registerCommands 방법 을 가 져 옵 니 다. 이 방법 은 CommandFactory 의 registerCommands () 방법 과 동명 이기 때문에 원본 코드 를 읽 는 과정 에서 사람들의 이목 을 헷 갈 리 게 하기 쉬 우 므 로 조심해 야 합 니 다.
  • 반사 적 인 방식 으로 매개 변수 류 예제 의 registerCommands 방법 을 얻 은 후 invoke 호출 을 직접 사용 하여 매개 변 수 를 CommandFactory 인 스 턴 스 factory 에 계속 전송 합 니 다.(공사 설계 상 교묘 하지만 읽 기 가 힘들다)
  • 다음 방법 은 Fs Command. registerCommands 로 호출 합 니 다.
      public static void registerCommands(CommandFactory factory) {
        factory.registerCommands(AclCommands.class);
        factory.registerCommands(CopyCommands.class);
        factory.registerCommands(Count.class);
        factory.registerCommands(Delete.class);
        factory.registerCommands(Display.class);
        factory.registerCommands(FsShellPermissions.class);
        factory.registerCommands(FsUsage.class);
        factory.registerCommands(Ls.class);
        factory.registerCommands(Mkdir.class);
        factory.registerCommands(MoveCommands.class);
        factory.registerCommands(SetReplication.class);
        factory.registerCommands(Stat.class);
        factory.registerCommands(Tail.class);
        factory.registerCommands(Test.class);
        factory.registerCommands(Touch.class);
        factory.registerCommands(SnapshotCommands.class);
        factory.registerCommands(XAttrCommands.class);
      }

    순환 하 는 느낌 이 듭 니 다. factory. registerCommands, Fs Command 하위 클래스 의 registerCommands 방법 을 계속 실행 합 니 다.
    Copy Commands 를 골 라 서 들 어가 서 실례 와 명령 행 인자 의 매 핑 관 계 를 볼 수 있 습 니 다
      public static void registerCommands(CommandFactory factory) {
        factory.addClass(Merge.class, "-getmerge");
        factory.addClass(Cp.class, "-cp");
        factory.addClass(CopyFromLocal.class, "-copyFromLocal");
        factory.addClass(CopyToLocal.class, "-copyToLocal");
        factory.addClass(Get.class, "-get");
        factory.addClass(Put.class, "-put");
        factory.addClass(AppendToFile.class, "-appendToFile");
      }
    

    총결산
    반사 적 인 방식 으로 인 스 턴 스 와 명령 행 매개 변수 에 대한 매 핑 관 계 를 층 층 이 등록 하고 인 스 턴 스 등록 트 리 를 구축 하여 공정 화 와 공정 확장 에 편리 하 므 로 여러분 이 축적 할 가치 가 있 습 니 다.

    좋은 웹페이지 즐겨찾기