HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)

Hadoop中HDFS的Java Api-----FileSystem的具体用法:

参考:https://www.cnblogs.com/dj-blog/p/9178465.html
注意:
1>上传文件的前提:必须在hdfs中先创建一个文件 create
2>下载文件的前提:必须在hdfs中先打开这个文件 open
3> user的含义:HADOOP_USER_NAME
HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第1张图片
HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第2张图片
4>conf的作用:
HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第3张图片
5>fileSystem的层次结构:
HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第4张图片

①创建文件夹:mkdirs默认就会递归的创建出多级目录

public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //创建文件夹的方式:可以迭代创建
         fileSystem.mkdirs(new Path("hdfs://hadoop20:9000/dir1/dir2"));
	}
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第5张图片

②从本地文件系统(本地参考的是eclipse安装在linux上还是windows上)上传文件到HDFS上(注意:目标文件的名字可以和源文件的名字不同,内容同样会拷贝)

public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //从本地上传文件到HDFS
         FSDataOutputStream fw = fileSystem.create(new Path("/dir1/dir2/file.txt"));
         FileInputStream fr = new FileInputStream("C:\\file.txt");
         IOUtils.copyBytes(fr,fw,1024,true);
	}
}

上面的代码也可以用下面简单的代码来替代:

public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //从本地上传文件到HDFS
         fileSystem.copyFromLocalFile(new Path("C:\\file.txt"), new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"));
	}
}

③从HDFS中下载文件到本地(本地参考的是eclipse安装在linux上还是windows上)

public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //从hdfs中下载文件到本地
         FSDataInputStream fr = fileSystem.open(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"));
         IOUtils.copyBytes(fr,System.out, 1024, true);
	}
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第6张图片
当然,上面的代码也可以用下面的代码来替代:

public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //从hdfs中下载文件到本地
         fileSystem.copyToLocalFile(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"));
	}
}

运行结果:
HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第7张图片  
调试方式:

fileSystem.copyToLocalFile(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"));
         改为:
         fileSystem.copyToLocalFile(false,new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"),true);

错误原因:
在使用copyToLocalFile(Path src, Path dst)方法时可能导致 setPermission文件本地文件效验失败,因此使用copyToLocalFile( boolean delSrc,Path src, Path dst, boolean useRawLocalFileSystem),其中:
boolean delSrc 指是否将原文件删除
Path src 指要下载的文件路径
Path dst 指将文件下载到的路径
boolean useRawLocalFileSystem 是否开启文件效验

④删除文件或者文件夹(会递归到下层,不会到上层)

public boolean delete(Path f, boolean recursive) throws IOException
如果f是一个文件或空目录,那么recursive的值就会被忽略:
/user/mart_cfo/word.txt
/user/mart_risk
如果f不是一个空目录:只有在recrusive值为true时,非空目录及其子内容才会被删除(否则会抛出IOException异常)。
/user/mart_risk/jdk1.7.0_25x64.zip
public class App1
{
     public static void main(String[] args) throws Exception
	{
		 Configuration conf = new Configuration();
         FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
         
         //删除文件或文件夹:第二个参数代表是否递归删除,类似于Python的那个
         fileSystem.delete(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), false);
	}
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第8张图片 
(5)mv操作(叫做rename)

import java.io.FileInputStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

public class hdfs_utils_1
{

	  public static void main(String[] args) throws Exception
      {
		  Configuration config = new Configuration();
          FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop11:9000"), config,"root");
          
          //mv操作:竟然叫做rename
          fileSystem.rename(new Path("/word.txt") ,new Path("/user/mart_cfo/"));
          
      }   
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第9张图片

(6)获取文件或者文件夹的元数据信息
第一:listFiles只能列出文件的信息(而且提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.

import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;


public class hdfs_utils_1
{

	  public static void main(String[] args) throws Exception
      {
		  
		  Configuration config = new Configuration();
          FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop11:9000/"), config,"dd_edw");
          
          
          //listFiles只能列出文件的信息(而且提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
          RemoteIterator listFiles = fileSystem.listFiles(new Path("/"), true);
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //时间戳转化为时间.
          
          
          while(listFiles.hasNext())
          {
        	  LocatedFileStatus file = listFiles.next();
        	  
        	  System.out.printf("文件路径是:%s\n", file.getPath());
        	  System.out.printf("文件名字:%s\n", file.getPath().getName());
        	  System.out.printf("文件修改时间:%s\n", simpleDateFormat.format(new Date(file.getModificationTime())));
        	  System.out.printf("文件访问时间:%s\n", simpleDateFormat.format(new Date(file.getAccessTime())));
        	  System.out.printf("文件所有者:%s\n", file.getOwner());
        	  System.out.printf("文件对应权限是:%s\n", file.getPermission());
        	  System.out.printf("文件对应的块大小:%s 字节\n", file.getBlockSize());
        	  System.out.printf("文件对应的大小:%s 字节\n", file.getLen());
        	  System.out.printf("文件对应的副本数:%s 个\n", file.getReplication());
        	  
        	  BlockLocation[] blockLocations = file.getBlockLocations();
        	  System.out.printf("文件对应%s 个block块.",blockLocations.length);
        	  for (BlockLocation blockLocation : blockLocations)
			  {
        		  System.out.printf("blocks块对应的位置是:");
        		  String[] hosts = blockLocation.getHosts();
				  for (String string : hosts)
				  {
					  System.out.println(string);
				  }
			  }
        	  
        	  System.out.println("------------------------------");
        	    
          }
          
      }   
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第10张图片

第二:listStatus可以列出某个指定目录下面文件和文件夹的信息(但是不提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.

public class hdfs_utils_1
{

	public static void main(String[] args) throws Exception
	{

		Configuration config = new Configuration();
		FileSystem fileSystem = FileSystem.get(
				new URI("hdfs://hadoop11:9000/"), config, "dd_edw");

		// listStatus可以列出某个指定目录下面文件和文件夹的信息(但是不提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
		FileStatus[] listStatus = fileSystem.listStatus(new Path("/"));
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss"); // 时间戳转化为时间.

		for (FileStatus fileStatus : listStatus)
		{

			System.out.printf("是否是文件夹:%s \n", fileStatus.isDirectory());
			System.out.printf("是否是文件:%s \n", fileStatus.isFile());

			System.out.printf("文件或者文件夹的路径是:%s\n", fileStatus.getPath());
			System.out.printf("文件或者文件夹的名字:%s\n", fileStatus.getPath().getName());

			System.out.printf("文件或者文件夹的修改时间:%s\n", simpleDateFormat.format(new Date(fileStatus.getModificationTime())));
			System.out.printf("文件或者文件夹的修改时间:%s\n", simpleDateFormat.format(new Date(fileStatus.getAccessTime())));

			System.out.printf("文件或者文件夹的修改时间:%s\n", fileStatus.getOwner());
			System.out.printf("文件或者文件夹的权限是:%s\n", fileStatus.getPermission());
			System.out.printf("文件或者文件夹的块大小:%s 字节\n", fileStatus.getBlockSize());
			System.out.printf("文件或者文件夹的对应的大小:%s 字节\n", fileStatus.getLen());
			System.out.printf("文件或者文件夹的对应的副本数:%s 个\n",fileStatus.getReplication());

			//好像不能获取到block对应的host位置.

			System.out.println("------------------------------");

		}

	}
}

HDFS的Java Api-----FileSystem的用法详解(fileSystem|filesystem)_第11张图片
(7)判断文件或者文件夹是否存在

public class WordCount
{
     public static String path = "/user/mart_cfo/";      //文件夹后面加不加/无所谓.
     
     public static void main(String[] args) throws IOException
     {
    	 Configuration config = new Configuration();
    	 config.set("fs.default.name", "hdfs://hadoop11:9000");
    	 
    	 FileSystem fileSystem = FileSystem.get(config);
    	 
    	 
    	 //判断文件或者文件夹是否存在.
    	 if (fileSystem.exists(new Path(path)))
    	 {
    		 System.out.printf("%s 路径已经存在!",path);
    	 }
    	 else {
    		 System.out.printf("%s 路径不存在!",path);
		 }	 
     }
}

对于以上问题,如有问题,欢迎留言指正!

你可能感兴趣的:(Hadoop,Hadoop-Skill)