Hadoop 利用FileSystem API 执行hadoop文件读写操作
因为HDFS不同于一般的文件系统,所以Hadoop提供了强大的FileSystem API来操作HDFS. 核心类是FSDataInputStream和FSDataOutputStream 读操作: 我们用FSDataInputStream来读取HDFS中的指定文件(第一个实验),另外我们还演示了这个类的定位文件位置的能力,然后从指定位置开始读取文件(第二个实验)。 代码如下: /* */ packagecom.charles.hadoop.fs; importjava.net.URI; importorg.apache.hadoop.conf.Configuration; importorg.apache.hadoop.fs.FSDataInputStream; importorg.apache.hadoop.fs.FileSystem; importorg.apache.hadoop.fs.Path; importorg.apache.hadoop.io.IOUtils; /** * *Description:查看Hadoop文件系统中的文件,利用hadoopFileSystem接口中的FSDataInputStream *FSDataInputStream还具有流定位的能力,可以从文件的任意位置开始读取 * *@authorcharles.wang *@createdMay26,201212:28:49PM * */ publicclassReadFromHadoopFileSystem{ /** *@paramargs */ publicstaticvoidmain(String[]args)throwsException{ //TODOAuto-generatedmethodstub //第一个参数传递进来的是hadoop文件系统中的某个文件的URI,以hdfs://ip的theme开头 Stringuri=args[0]; //读取hadoop文件系统的配置 Configurationconf=newConfiguration(); conf.set("hadoop.job.ugi","hadoop-user,hadoop-user"); //FileSystem是用户操作HDFS的核心类,它获得URI对应的HDFS文件系统 FileSystemfs=FileSystem.get(URI.create(uri),conf); FSDataInputStreamin=null; try{ //实验一:输出全部文件内容 System.out.println("实验一:输出全部文件内容"); //让FileSystem打开一个uri对应的FSDataInputStream文件输入流,读取这个文件 in=fs.open(newPath(uri)); //用Hadoop的IOUtils工具方法来让这个文件的指定字节复制到标准输出流上 IOUtils.copyBytes(in,System.out,50,false); System.out.println(); //实验二:展示FSDataInputStream文件输入流的流定位能力,用seek进行定位 System.out.println("实验二:展示FSDataInputStream文件输入流的流定位能力,用seek进行定位"); //假如我们要吧文件输出3次 //第一次输入全部内容,第二次输入从第20个字符开始的内容,第3次输出从第40个字符开始的内容 for(inti=1;i<=3;i++){ in.seek(0+20*(i-1)); System.out.println("流定位第"+i+"次:"); IOUtils.copyBytes(in,System.out,4096,false); } }finally{ IOUtils.closeStream(in); } } } 我们传入的命令行参数为我们要读的HDFS文件系统中某文件的URI: hdfs://192.168.129.35:9000/user/hadoop-user/textfile.txt 最终输出结果为: 实验一:输出全部文件内容 Thisisatextfileeditedbycharlestotestthehadoopdistributedfilesystem'sfeatures. 实验二:展示FSDataInputStream文件输入流的流定位能力,用seek进行定位 流定位第1次: Thisisatextfileeditedbycharlestotestthehadoopdistributedfilesystem'sfeatures. 流定位第2次: editedbycharlestotestthehadoopdistributedfilesystem'sfeatures. 流定位第3次: 写操作: 我们用FSDataOutputStream来写文件到HDFS系统中,或者说从本地文件系统中复制文件到HDFS文件系统中。其中这个本地文件系统是相对于运行这段java代码的宿主系统。 代码如下: /* */ packagecom.charles.hadoop.fs; importjava.io.BufferedInputStream; importjava.io.FileInputStream; importjava.io.InputStream; importjava.io.OutputStream; importjava.net.URI; importorg.apache.hadoop.conf.Configuration; importorg.apache.hadoop.fs.FileSystem; importorg.apache.hadoop.fs.Path; importorg.apache.hadoop.io.IOUtils; importorg.apache.hadoop.util.Progressable; /** * *Description:这个类展示如何将一个文件从本地文件系统复制到HDFS * *@authorcharles.wang *@createdMay26,20121:00:39PM * */ publicclassWriteToHadoopFileSystem{ /** *@paramargs */ publicstaticvoidmain(String[]args)throwsException{ //TODOAuto-generatedmethodstub //两个参数分别是本地文件系统的的输入文件路径和HDFS中的输出文件位置 //如果这段代码最终运行在Hadoop所在的服务器上,那么本地文件系统是相对于那台服务器的本地文件系统 //如果这段代码运行在我们WindowsPC上,那么本地文件系统是这台WindowPC的文件系统 StringlocalSrc=args[0]; Stringdst=args[1]; //因为本地文件系统是基于java.io包的,所以我们创建一个本地文件输入流 InputStreamin=newBufferedInputStream(newFileInputStream(localSrc)); //读取hadoop文件系统的配置 Configurationconf=newConfiguration(); conf.set("hadoop.job.ugi","hadoop-user,hadoop-user"); //仍然用FileSystem和HDFS打交道 //获得一个对应HDFS目标文件的文件系统 FileSystemfs=FileSystem.get(URI.create(dst),conf); //创建一个指向HDFS目标文件的输出流 OutputStreamout=fs.create(newPath(dst)); //用IOUtils工具将文件从本地文件系统复制到HDFS目标文件中 IOUtils.copyBytes(in,out,4096,true); System.out.println("复制完成"); } } 我们传入2个命令行参数,一个是本地文件系统中被复制的文件路径,第二个要复制到的HDFS文件系统中的目标文件路径: copyMe.txt hdfs://192.168.129.35:9000/user/hadoop-user/copyMe.txt 我们去文件系统中去检查文件,果然文件被复制上去了: 打开这个目标文件,果然内容与预期一样: 本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/878921,如需转载请自行联系原作者