java 读取hdfs文件,注意事项

昨天在写java读取hdfs文件的时候一直报错

java.io.IOException: No FileSystem for scheme: hdfs

,这个问题纠结了很长时间(尝试添加core-site.xml,hdfs-site.xml,map-site.xml.等等)都尝试了,还是失败,最终问题原因找到了在于https://www.cnblogs.com/justinzhang/p/4983673.html

发现与hadoop filesystem相关的包有两个,分别是:hadoop-hdfs-2.7.1.jar和hadoop-common-2.7.1.jar,这两个包的META-INF中的services目录下,都有如下的内容:

 

可以看到,这两个包的services目录下都有,org.apache.hadoop.fs.FileSystem这个文件。使用Maven-assembly-plugin的时候,会将所有依赖的包unpack,然后在pack,这样就会出现,同样的文件被覆盖的情况,我们看下打好的包中保留的是啥:

 

 

可以看到,maven-assembly-plugin(fatjar也是一样的),将hadoop-common.jar中的services内容打进了最终的jar包中,而hadoop-hdfs.jar包中,services的内容被覆盖了。由于我们的函数调用是这样写的

image

在函数中使用了hdfs://IP : port的schema,而在生成的最终jar包中,无法找到这个schema的实现。所以就抛出了

java.io.IOException: No FileSystem for scheme: hdfs

解决方案是,在设置hadoop的配置的时候,显示设置这个类:"org.apache.hadoop.hdfs.DistributedFileSystem:

configuration.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");

然后在重新打包,一切works ok了。

 

 

//读取文件夹,写入出文件
    public void readFileWriteItOnCdh(String hdfsDir,String url) throws  Exception {
        Configuration conf = new Configuration();// 读取配置文件\
        conf.set("fs.defaultFS", "hdfs://hadoop4:8020");
        conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");        
        Path outPath = new Path(hdfsDir);
        FileSystem hdfs = outPath.getFileSystem(conf);// 创建输出路径
//        if (hdfs.isDirectory(outPath)) {
//            hdfs.delete(outPath, true);
//        }
           
           RemoteIterator<LocatedFileStatus> iterator = hdfs.listFiles(new Path(hdfsDir), true);
           while (iterator.hasNext()) {
               LocatedFileStatus status = iterator.next();
               Path filePath = status.getPath();
               String fileName = filePath.getName();
//               System.out.println(fileName);
               String dsf = hdfsDir+fileName;
               
               FileSystem fs = FileSystem.get(URI.create(dsf),conf);
               FSDataInputStream hdfsInStream = fs.open(new Path(dsf));
               
               byte[] bytes = new byte[1024];
               int len = -1;
               ByteArrayOutputStream stream = new ByteArrayOutputStream();
        
               while ((len = hdfsInStream.read(bytes)) != -1) {
                   stream.write(bytes, 0, len);
               }
               hdfsInStream.close();
               stream.close();
               WriteLocal.method1(url,new String(stream.toByteArray()) );
           }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值