HDFS学习之客户端API操作
org.apache.hadoop.fs.FileSystem是Hadoop中一个相当通用的文件系统的抽象基类,它是一个面向最终用户的接口类。应该将所有可能使用Hadoop分布式文件系统的用户代码编写为使用一个FileSystem对象。Hadoop DFS是一种多机系统,显示为单个磁盘,由于其容错能力和潜在的超大容量而非常有用。
当使用Hadoop的API进行开发,使用HDFS文件系统的时候,必定会用到Hadoop中的FileSystem抽象类,通过FileSystem类的get的方法获取FileSystem的实例,并通过该实例来进行文件系统的操作。注意,该类是一个抽象类,并不能直接通过new关键字创建对象,而是通过静态工厂方法获取具体的对象。获取方式有以下两种:
/**
* Get a filesystem instance based on the uri, the passed
* configuration and the user
* @param uri of the filesystem
* @param conf the configuration to use
* @param user to perform the get as
* @return the filesystem instance
* @throws IOException
* @throws InterruptedException
*/
public static FileSystem get(final URI uri, final Configuration conf, final String user) throws IOException, InterruptedException {
…… } /** * Returns the configured filesystem implementation. * @param conf the configuration to use */ public static FileSystem get(Configuration conf) throws IOException { return get(getDefaultUri(conf), conf); }
这两种方法区别在于参数的数量不相同,第一种需要文件系统的访问地址,也就是这个文件系统对象是基于哪个filesystem的;第二个参数就是Configuration对象,该对象主要用于加载配置文件,第三个参数是作为哪个用户执行get方法。
第二种方法,参数只有一个,就是Configuration对象,如果Configuration对象事先没有指定文件系统的地址,那么就会默认访问本地的文件系统。
一、文件上传操作
public void testClient() throws IOException, URISyntaxException, InterruptedException { // 1.获取文件系统 Configuration conf = new Configuration(); // 配置在集群上运行// get方法的三个参数final URI uri, final Configuration conf,final String user // 根据给定的URI、传递的配置信息以及用户名,获取文件系统实例 FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"), conf, "fym000"); fs.copyFromLocalFile(new Path("F:/jdk/jdk-8u144-linux-x64.tar.gz"),new Path("/fym/pyx/kak/jdk-8u144-linux-x64.tar.gz")); // 关闭资源 fs.close(); }
二、文件下载
@Test public void downloadFile() throws URISyntaxException, IOException, InterruptedException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"),conf,"fym000"); // boolean delSrc, 是否在下载完成后将源文件删除 // Path src, 要下载的文件路径 // Path dst, 文件下载后要保存的路径 // boolean useRawLocalFileSystem 是否使用本地文件系统,因为本地文件系统并不是CRC文件系统, // 所以使用本地文件系统不会产生crc文件 fs.copyToLocalFile(false,new Path("/fym/pyx/lll/520.txt"),new Path("./"),true); fs.close(); }
三、文件删除
@Test public void deleteFile() throws URISyntaxException, IOException, InterruptedException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"),conf,"fym000"); // Path f, boolean recursive // 第一个参数是在HDFS上要删除的文件的路径;第二个参数是如果给定的路径是一个文件夹,则设置为true进行递归删除,否则会报出异常 fs.delete(new Path("/fym/pyx/lll/523.txt"),true); fs.close(); }
四、文件重命名
@Test public void renameFile() throws URISyntaxException, IOException, InterruptedException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"),conf,"fym000"); // Renames Path src to Path dst. fs.rename(new Path("/fym/pyx/lll/520.txt"),new Path("/fym/pyx/lll/525.txt")); fs.close(); }
五、查看文件的详细信息
@Test public void listFiles() throws URISyntaxException, IOException, InterruptedException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"), conf, "fym000"); RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/fym/pyx/kak"), true); // 获取文件详情 while (listFiles.hasNext()){ LocatedFileStatus status = listFiles.next(); // 输出详情 // 文件名称 System.out.println(status.getPath().getName()); // 长度 System.out.println(status.getLen()); // 权限 System.out.println(status.getPermission()); // 分组 System.out.println(status.getGroup()); // Get the file's block locations,返回值是一个BlockLocation类型的数组 // BlockLocation这个类用于表示块的网络位置,包含块副本的主机的相关信息,以及其他块的元数据,比如与该块关联的文件偏移量 // 块的长度、是否损坏等 BlockLocation[] blocks = status.getBlockLocations(); for (BlockLocation block : blocks) { // Get the list of hosts (hostname) hosting this block, // 获取托管此块的主机列表(主机名) System.out.println("托管此块的主机列表(主机名)"); String[] hosts = block.getHosts(); for (String host : hosts) { System.out.println(host); } System.out.println("获取托管块的缓存副本的主机列表(主机名)"); // Get the list of hosts (hostname) hosting a cached replica of the block, // 获取托管块的缓存副本的主机列表(主机名) String[] cachedHosts = block.getCachedHosts(); for (String cachedHost : cachedHosts) { System.out.println(cachedHost); } // 获取块的长度 System.out.println("获取块的长度"); System.out.println(block.getLength()); // Get the list of names (IP:xferPort) hosting this block // 获取托管此块的名称列表(IP:xferPort) System.out.println("获取托管此块的名称列表(IP:xferPort)"); String[] names = block.getNames(); for (String name : names) { System.out.println(name); } // Get the start offset of file associated with this block // 获取与此块关联的文件的起始偏移量 System.out.println("获取与此块关联的文件的起始偏移量"); System.out.println(block.getOffset()); } System.out.println("**********************************"); } fs.close(); }
输出结果:
jdk-8u144-linux-x64.tar.gz 185515842 rw-r--r-- supergroup 托管此块的主机列表(主机名) hadoop103 hadoop101 hadoop102 获取托管块的缓存副本的主机列表(主机名) 获取块的长度 134217728 获取托管此块的名称列表(IP:xferPort) 192.168.182.103:50010 192.168.182.101:50010 192.168.182.102:50010 获取与此块关联的文件的起始偏移量 0 托管此块的主机列表(主机名) hadoop103 hadoop101 hadoop102 获取托管块的缓存副本的主机列表(主机名) 获取块的长度 51298114 获取托管此块的名称列表(IP:xferPort) 192.168.182.103:50010 192.168.182.101:50010 192.168.182.102:50010 获取与此块关联的文件的起始偏移量 134217728 **********************************
六、判断所给的路径f是文件还是文件夹
public void isFileorDir() throws URISyntaxException, IOException, InterruptedException { Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(new URI("hdfs://192.168.182.101:9000"), conf, "fym000"); // 参数 Path f // 如果路径f是目录,列出给定路径中文件/目录的状态。 FileStatus[] listStatus = fs.listStatus(new Path("/")); for (FileStatus status : listStatus) { if(status.isDirectory()){ System.out.println("dir:"+status.getPath().getName()); }else { System.out.println("fil"+status.getPath().getName()); } } fs.close(); }
当前路径下内容:
程序输出结果:
dir:fym
dir:sanguo