基于Hadoop的简易数据云盘系统的实现【升级版】

1. 引言

项目来源《Hadoop大数据开发案例教程与项目实战》

开发一款基于Hadoop的数据云盘,来理解开发的原理和Hadoop相关知识点,学会Hdoop、HDFS的操作以及JavaWeb的开发。

现在将成果进行总结和记录。

2. 项目简介

网盘是基于云计算理念推出的企业数据网络存储和管理解决方案,利用互联网后台数据中心的海量计算和存储能力为企业提供数据汇总分发、存储备份和管理等服务。

本文基于Hadoop开发这样的一个系统,主要包括系统前台、系统后台两个部分。后台采用JEE常见的开发框架,使用Hadoop的伪分布文件系统存储文件。

3. 功能需求

主要功能:登录、注册、上传、查询、下载、删除

开发环境:IDEA/JDK1.8/MySQL5/Hadoop伪分布

4. 系统开发

4.1 环境搭建(升级版本)

原书使用的是普通JavaWeb工程,本系统升级使用SpringBoot2,使用前端框架layui美化了界面,将工程代码上传到github。

具体可查看,地址为:https://github.com/fanling521/fanlcloud

基于Hadoop的简易数据云盘系统的实现【升级版】_第1张图片

4.2 登录注册

使用Apache Shiro实现权限登录,使用的是SpringBoot集成Apache Shiro,具体配置信息看代码和注释

(1)简单版本的用户表 

基于Hadoop的简易数据云盘系统的实现【升级版】_第2张图片

(2)登录注册界面设计

基于Hadoop的简易数据云盘系统的实现【升级版】_第3张图片

没有账号,需要先注册。 

 

基于Hadoop的简易数据云盘系统的实现【升级版】_第4张图片

创建用户,同时创建对应的用户文件夹,上传的文件都会在这个目录下。 

基于Hadoop的简易数据云盘系统的实现【升级版】_第5张图片

当一个非管理员用户登录时候,上传文件

基于Hadoop的简易数据云盘系统的实现【升级版】_第6张图片

下载

基于Hadoop的简易数据云盘系统的实现【升级版】_第7张图片 

 删除文件

 4.2 操作HDFS

package com.fanling.fanlcloud.service.impl;

import com.fanling.fanlcloud.config.MyConfig;
import com.fanling.fanlcloud.pojos.HDFSFileStatus;
import com.fanling.fanlcloud.service.HDFSService;
import com.fanling.fanlcloud.utils.string.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

/**
 * hdfs操作类
 */
@Service
public class HDFSServiceImpl implements HDFSService {
    private final Logger logger = LoggerFactory.getLogger(HDFSServiceImpl.class);
    //创建文件时候的主目录

    @Autowired
    protected MyConfig config;

    /**
     * 创建文件夹
     *
     * @param loginId 登录名
     * @return
     */
    @Override
    public Boolean mkDir(String loginId) {
        try {
            logger.info("---创建用户文件夹----" + loginId);
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(config.getHdfsDir()), conf);
            return fs.mkdirs(new Path(config.getHdfsFullPath() + "/" + loginId));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 上传文件
     *
     * @param localPath
     * @param remoteFileName 格式 (loginId)/fileName.xx
     */
    public void putFile(String localPath, String remoteFileName) {
        try {
            logger.info("---上传----" + localPath);
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(config.getHdfsDir()), conf);
            fs.copyFromLocalFile(true, new Path(localPath), new Path(config.getHdfsPath() + "/" + remoteFileName));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载文件
     *
     * @param localPath 本地文件路径
     * @param hdfsPath  远程路径 例子:/user/fanl/cloud/fanling/xx.png
     */
    public Boolean getFile(String localPath, String hdfsPath) {
        try {
            logger.info("---下载----" + hdfsPath);
            logger.info("---到本地----" + localPath);
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(config.getHdfsFullPath()), conf);
            //这里穿文件名就行,因为暂且没有创建文件夹的活动
            hdfsPath = config.getHdfsDir() + hdfsPath;
            String fileName = hdfsPath.substring(hdfsPath.lastIndexOf("/"));
            //判断下载路径
            File dPath = new File(localPath);
            if (!dPath.exists()) {
                dPath.mkdirs();
            }
            fs.copyToLocalFile(new Path(hdfsPath), new Path(localPath + "\\" + fileName));
            logger.info("-----下载完成!");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除文件
     *
     * @param rmFilePath
     */
    public Boolean rmFile(String rmFilePath) {
        try {
            logger.info("---删除----" + rmFilePath);
            //补充前缀
            rmFilePath = config.getHdfsDir() + rmFilePath;
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(rmFilePath), conf);
            return fs.delete(new Path(rmFilePath), true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 遍历HDFS上的文件
     *
     * @return
     */
    public List lsFile(String loginId) {
        List list = new ArrayList<>();
        String listPath = config.getHdfsFullPath();
        try {
            //用户只能查看自己的目录,admin可以查看所有
            if (StringUtils.isNotEmpty(loginId)) {
                listPath = listPath + "/" + loginId;
            }
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create(config.getHdfsDir()), conf);
            logger.info(loginId + "查看目录:" + listPath);
            FileStatus[] fileList = fs.listStatus(new Path(listPath));
            if (fileList != null) {
                for (FileStatus fileStatus : fileList) {
                    HDFSFileStatus hdfsFileStatus = new HDFSFileStatus();
                    //文件名
                    hdfsFileStatus.setName(fileStatus.getPath().getName());
                    //路径
                    hdfsFileStatus.setDirPath(fileStatus.getPath().toString());
                    if (loginId.equals("admin")) {
                        //类型
                        hdfsFileStatus.setType("目录");
                    }
                    {
                        //类型
                        hdfsFileStatus.setType("文件");
                    }
                    //大小
                    hdfsFileStatus.setLen(Long.toString(fileStatus.getLen()));
                    list.add(hdfsFileStatus);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

 4.3 实现效果

基于Hadoop的简易数据云盘系统的实现【升级版】_第8张图片

5. 总结

遇到的困难

1. 整合Shiro中遇到无法读取登录用户的问题,经过排查是因为用了BeanUtils的复制属性的方法,导致getSubjct().getPrincipal()为空了,最后直接强制转换了 return (SysUser) getSubjct().getPrincipal();

2. 上传文件到HDFS导致路径问题,经过排查,是自己写的路径问题。

你可能感兴趣的:(Java开发,大数据,学习经历)