hadoop2.2.0 边角料(一)

本文详细解析了Hadoop中DFS客户端命令copyFromLocal的执行流程,从bin/hadoop脚本开始,逐步深入到FsShell类及CopyFromLocal类的具体实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hadoop dfs -copyFromLocal 是如何执行的?

  1. bin/hadoop脚本调用hdfs脚本
  2. hdfs调用org.apache.hadoop.fs.FsShell类
  3. FssShell的main函数调用
    res = ToolRunner.run(shell, argv);//shell是FsShell的一个实例
  4. ToolRunner.run调用的是FsShell中的run函数,其中
    instance = commandFactory.getInstance(cmd);
    if (instance == null) {
      throw new UnknownCommandException();
    }
    exitCode = instance.run(Arrays.copyOfRange(argv, 1, argv.length));
    copyCommands.java在CommandFactory中注册copy相关的命令
     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");
      }

  5. copyFromLocal类<=Put类<=CommandWithDestination类<=FsCommand类
    @Override
        protected void processOptions(LinkedList<String> args) throws IOException {
          CommandFormat cf = new CommandFormat(1, Integer.MAX_VALUE, "f", "p");
          cf.parse(args);
          setOverwrite(cf.getOpt("f"));
          setPreserve(cf.getOpt("p"));
          getRemoteDestination(args);
          // should have a -r option
          setRecursive(true);
        }
    
        // commands operating on local paths have no need for glob expansion
        @Override
        protected List<PathData> expandArgument(String arg) throws IOException {
          try {
            List<PathData> items = new LinkedList<PathData>();
            items.add(new PathData(new URI(arg), getConf()));
            return items;
          } catch (URISyntaxException e) {
            throw new IOException("unexpected URISyntaxException", e);
          }
        }
    
        @Override
        protected void processArguments(LinkedList<PathData> args)
        throws IOException {
          // NOTE: this logic should be better, mimics previous implementation
          if (args.size() == 1 && args.get(0).toString().equals("-")) {
            copyStreamToTarget(System.in, getTargetPath(args.get(0)));
            return;
          }
          super.processArguments(args);
        }
    procesOptions用于解析参数,expandArgument没看明白,processArguments做实际工作,调用copyStreamToTarget完成copy工作
  6. copyStreamToTarget创建TargetFileSystem实例targetFs,TargetFileSystem<=FilterFileSystem<=FileSystem
        TargetFileSystem targetFs = new TargetFileSystem(target.fs);
        try {
          PathData tempTarget = target.suffix("._COPYING_");
          targetFs.setWriteChecksum(writeChecksum);						//跟踪代码发现这个函数貌似什么都没做
          targetFs.writeStreamToFile(in, tempTarget);
          targetFs.rename(tempTarget, target);
        } finally {
          targetFs.close(); // last ditch effort to ensure temp file is removed
        }

  7. writeStreamToFile代码

    void writeStreamToFile(InputStream in, PathData target) throws IOException {
      FSDataOutputStream out = null;
      try {
        out = create(target);
        IOUtils.copyBytes(in, out, getConf(), true);
      } finally {
        IOUtils.closeStream(out); // just in case copyBytes didn't
      }
    }
本帖最后由 591691826 于 2013-4-10 13:32 编辑 0.我只说些常用的以及目前用的到的 1.下载附件。解压后拷到c:windows\system32里面。 2.打开运行(快捷键windows键+R)输入cmd 回车。 3.输入adb devices 可以获取当前连接的设备。 4.输入adb shell 回车 接着输入su。这时候$变成#。说明你已经取得权限了,可以进行各项调试命令了。 5.如果要从电脑上传送文件到手机的话,使用adb push命令。格式:adb push 本地路径 手机路径 ;举例:把c盘根目录下的456.txt传送到system。则:adb push c:\456.txt /system/ 传送文件到system文件夹的话。需要先挂载system分区。再改读写权限。 如下:mount -o rw,remount -t yaffs2 /dev/block/mtdblock1 /system回车 (这是挂载分区) chmod 777 /system回车 (修改权限为可读) 这两步做完后退出shell指令端(exit回车 exit回车)就可以push文件到system里面去了。 如果push文件到sdcard卡的话。一般来说直接push就行。如果出现premission denied 的话,需要修改sdcard权限为可读写。即chmod 777 sdcard。 6。adb pull 是从手机传送文件到电脑上。格式: adb pull 手机路径 电脑路径 。会push的话pull很简单。大同小异嘛。 7.关于这个地方的权限,具体说下: 在Unix和Linux的各种操作系统下,每个文件(文件夹也被看作是文件)都按读、写、运行设定权限。例如我用ls -l命令列文件表时,得到如下输出: -rw-r--r-- 1 bu users 2254 2006-05-20 13:47 tt.htm 从第二个字符起rw-是说用户bu有读、写权,没有运行权,接着的r--表示用户组users只有读权限,没有运行权,最后的r--指其他人(others)只有读权限,没有写权和运行权。这是系统默认设置,我可以改写tt.htm,同组的人和其他人只有权读,没人有权运行,因为只是一个html文件,不必运行。这在Novell的directory services之前很先进。 读、写、运行三项权限可以用数字表示,就是r=4,w=2,x=1。所以,rw-r--r--用数字表示成644。 反过来说777就是rwxrwxrwx,意思是该登录用户(可以用命令id查看)、他所在的组和其他人都有最高权限。 再多说一句。我用chmod o-r tt.htm命令改权限,o-r是others的权限中减掉读。结果是 -rw-r----- 1 bu users 2254 2006-05-20 13:47 tt.htm 如果用命令chmod 777 tt.htm,结果是 -rwxrwxrwx 1 bu users 2254 2006-05-20 13:47 tt.htm 任何人都有读、写、运行三项权限。8。以后比如替换系统文件神马的不能开机。可以通过救援模式下adb命令替换系统文件并该权限即可。 .想写的就是这么多了。仅把我的心得告诉大家。内容编辑可能有些混乱。不好意思。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值