JAVA API实现HDFS操作(二)操作函数

说明:在IDEA集成环境中利用JAVA API实现目录的创建、文件的创建、文件的上传和下载、文件的查看、文件删除、文件的编辑等操作。以下代码均创建在my.dfs包下


创建文件夹

在hdfs系统的根目录下创建文件夹 /hdfstest
验证程序执行结果:

$hadoop fs -ls -R /

package my.hdfs;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
在hdfs系统的根目录下创建文件夹 /hdfstest
*/
public class MakeDir {
    public static void main(String[] args) throws IOException, URISyntaxException {
        // 创建 Configuration 对象
        Configuration conf = new Configuration();

        // FileSystem默认的端口号:9000
        String hdfsPath = "hdfs://localhost:9000";

        // 获取 FileSystem 对象
        FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
        String newDir = "/hdfstest";
        
		// 如果创建成功将返回true
        boolean result = hdfs.mkdirs(new Path(newDir));

        if (result) {
            System.out.println("Success!");
        } else {
            System.out.println("Failed!");
        }
    }
}

迭代文件夹获取文件信息

设置文件夹,迭代获取其下的文件和文件信息(权限、所有者、所在组、文件所在路径)

package my.hdfs;

import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;

import java.io.IOException;
import java.net.URI;


public class IteratorListFiles {
    public static void main(String[] args) throws IOException {
        FileSystem hdfs = FileSystem.get(URI.create("hdfs://localhost:9000/"), new Configuration());

        String watchHDFS = "/";
        iteratorListFile(hdfs, new Path(watchHDFS));
    }

    public static void iteratorListFile(FileSystem hdfs, Path path) throws IOException {

        FileStatus[] files = hdfs.listStatus(path);

        for (FileStatus file: files) {
            if (file.isDirectory()) {
                System.out.println("dir:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
            } else if(file.isFile()){
                System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
            }
        }
    }
}

操作文件

创建、重命名、删除文件、判断文件是否存在

package my.hdfs;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

/**
创建、重命名、删除文件、判断文件是否存在、迭代文件夹获取其下的文件和文件夹信息
*/
public class OperateFile {
    public static void main(String[] args) throws IOException, URISyntaxException {

        // 创建 Configuration 对象
        Configuration conf = new Configuration();
        // FileSystem默认的端口号:9000
        String hdfsPath = "hdfs://localhost:9000";
        // 获取 FileSystem 对象
        FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);

        // 1. 迭代 /hdfstest 文件夹下所有的文件文件
        String watchHDFS = "/hdfstest";
        FileStatus[] files = hdfs.listStatus(new Path(watchHDFS));
        for (FileStatus file: files){
            if (file.isFile()) {
                System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
            }
        }

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

        // 2. create file。如果文件所在的文件夹不存在,那么会自动创建文件夹
        String filePath = "/hdfstest/src_data";
        FSDataOutputStream create = hdfs.create(new Path(filePath));
        System.out.println("create file successfully!" + create);


        // 3. 重命名 hdfs.rename() src_data -> dst_data
        Path src = new Path("/hdfstest/src_data");
        Path dst = new Path("/hdfstest/dst_data");
        System.out.println("rename file successfully?" + hdfs.rename(src, dst));
        // 判断文件是否存在 hdfs.exist() /hdfstest/src_data
        System.out.println("after rename,src_data is still exist?" + hdfs.exists(src));


        // 4. 删除文件 hdfs.delete() dst_data
        hdfs.delete(dst, true);
        // 判断文件是否存在 /hdfstest/dst_data
        System.out.println("after delete(), dst_data is still exist?" + hdfs.exists(dst));


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


        // 5. 迭代 /hdfstest 文件夹下所有的文件文件
        for (FileStatus file: files){
            if (file.isFile()) {
                System.out.println("file:" + file.getPermission() + " " + file.getOwner() + " " + file.getGroup() + " " + file.getPath());
            }
        }
    }
}

写入文件信息

在HDFS文件系统中创建/hdfstest/writefile文件,在文件中写入内容hello world hello data!

验证程序执行结果:

$hadoop fs -ls -R /hdfstest
$hadoop fs -cat /hdfstest/writefile

api实现代码:

package my.hdfs;

import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.Configuration;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/*
在HDFS文件系统中创建 /hdfstest/writefile 文件并在文件中写入内容 hello world hello data!
*/
public class WriteFile{
    public static void main(String[] args) throws IOException, URISyntaxException {

        // FileSystem.get(Configuration conf) 使用配置文件来获取文件系统, 配置文件conf/core-site.xml,若没有指定则返回local file system. (原来是这样)
        // FileSystem.get(URI uri, Configuration conf) 根据uri和conf来确定文件系统
        // 若 hdfs系统的uri 写错,则会默认为local文件系统,从当前java的Project文件所在的位置
        FileSystem hdfs = FileSystem.get(new URI("hdfs//localhost:9000"), new Configuration());

        String filePath = "/hdfstest/writefile";

        FSDataOutputStream create = hdfs.create(new Path(filePath));
        System.out.println("Step 1 Finish!");

        String sayHi = "hello world hello data!";
        byte[] buff = sayHi.getBytes();
        create.write(buff, 0, buff.length);

        create.close();
        System.out.println("Step 2 Finish!");
    }
}

合并文件内容

首先进入本地/data/hadoop目录下,将该目录下的所有文件删除(此时要求/data/hadoop中必须全是文件,不能有目录)。

$cd /data/hadoop
$sudo rm -r /data/hadoop/*

然后在该目录下新建两文件,分别命名为file1、file2。

$touch file1
$touch file2

向 file1 和 file2 中,分别输入内容如下

$echo "hello file1" > file1
$echo "hello file2" > file2

在 my.hdfs 包下,新建类 PutMerge,将 Linux 本地文件夹/data/hadoop/下的所有文件,上传到HDFS上并合并成一个文件/hdfstest/mergefile

验证程序执行结果:

$hadoop fs -ls /hdfstest

api代码实现

package my.hdfs;

import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.Configuration;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
将/data/hadoop下的所有文件上传至HDFS并合并文件内容
*/

public class PutMerge{
    public static void main(String[] args) throws IOException, URISyntaxException {
        Configuration conf = new Configuration();
        FileSystem hdfs = FileSystem.get(new URI("hdfs://localhost:9000"), conf);

        FileSystem local = FileSystem.getLocal(conf);

        String from_LinuxDir = "/data/hadoop/";
        String to_HDFS = "/hdfstest/mergefile";

        FileStatus[] inputFiles = local.listStatus(new Path(from_LinuxDir));

        FSDataOutputStream out = hdfs.create(new Path(to_HDFS));
        for (FileStatus file: inputFiles) {
            FSDataInputStream in = local.open(file.getPath());
            byte[] buffer = new byte[256];
            int bytesRead = 0;
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, bytesRead);   
            }
            in.close();
        }
        System.out.println("Finish!");
    }
}

文件上传与下载

HDFS文件下载至本地

  1. /data/hadoop/下创建目录 copytolocal。
$mkdir /data/hadoop/copytolocal
  1. 在my.hdfs包下,创建类CopyToLocalFile,程序功能是将 HDFS 文件系统上的文件/hdfstest/sample_data,下载到本地/data/hadoop/copytolocal
  2. 验证程序执行结果:
$cd /data/hadoop/copytolocal
$ls

api实现代码:

package my.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
将 HDFS 文件系统中的文件下载到本地 Linux 系统
*/
public class CopyToLocalFile{
    public static void main(String[] args) throws URISyntaxException, IOException {
        Configuration conf = new Configuration();
        String hdfsPath = "hdfs://localhost:9000";
        FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);
        
        String from_HDFS = "/hdfstest/sample_data";
        String to_Local = "/data/hadoop/copytolocal";

        hdfs.copyToLocalFile(false, new Path(from_HDFS), new Path(to_Local));
        System.out.println("Finish!");
    }
}

/hdfstest/sample_data等价于hdfs://localhost:9000/hdfstest/sample_data

若删除/,则hdfstest/sample_data表示:?

若无法将文件移至/data/hadoop/copytolocal,即为权限不够,终端输入:chomd -R 777 /data/hadoop/copytolocal

本地文件上传至HDFS

  1. 在 /data/hadoop 下创建 sample_data 文件
$cd /data/hadoop
$touch sample_data
  1. sample_data 文件中写入hello world
$echo "hello file1" > sample_data
  1. 在 my.hdfs 包下,创建类``CopyFromLocalFile.java,将本地 Linux 操作系统上的文件/data/hadoop/sample_data,上传到 HDFS 文件系统的/hdfstest` 目录下。
  2. 验证程序执行结果:
$hadoop fs -ls -R /

api实现代码:

package my.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/*
将本地文件上传到 HDFS 文件系统
*/
public class CopyFromLocalFile{
    public static void main(String[] args) throws IOException, URISyntaxException {
        Configuration conf = new Configuration();
        String hdfsPath = "hdfs://localhost:9000";
        FileSystem hdfs = FileSystem.get(new URI(hdfsPath), conf);

        String from_Linux = "/data/hadoop/sample_data";
        String to_HDFS = "/hdfstest";

        hdfs.copyFromLocalFile(new Path(from_Linux), new Path(to_HDFS));
        System.out.println("Finish!");
    }
}

文件块信息

在 my.hdfs 包下,新建类 LocateFile,程序功能是查看 HDFS 文件系统上,文件/hdfstest/sample_data的文件块信息

package my.hdfs;

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.Path;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

public class LocateFile{
    public static void main(String[] args) throws URISyntaxException, IOException {
        FileSystem hdfs = FileSystem.get(new URI("hdfs://localhost:9000"), new Configuration());
        
        Path file = new Path("/hdfstest/sample_data");
        FileStatus fileStatus = hdfs.getFileStatus(file);

        BlockLocation[] location = hdfs.getFileBlockLocations(fileStatus, 0, fileStatus.getLen());

        for (BlockLocation block: location) {
            String[] hosts = block.getHosts();
            for (String host: hosts){
                System.out.println("block:" + block + "host:" + host);
            }
        }
    }
}

获取FileSystem对象,详见:JAVA API实现HDFS操作(一)获取FileSystem

用Java API实现HDFS操作过程中的常见问题,详见:用Java API实现HDFS操作(三)问题汇总

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值