分布式系列~09.FastDFS 文件 (上传,下载,删除)

FastDFS 文件 (上传,下载,删除)

本文是上一篇文章的后续,详情点击该链接~

简介

       FastDFS是一个轻量级的开源分布式文件系统。自2008年4月份开始启动。类似google FS的一个轻量级分布式文件系统,C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。实现了软件方式的磁盘阵列(Redundant Arrays of Independent Drives,RAID),可以使用廉价的IDE(Integrated Drive Electronics)硬盘进行存储。并且支持存储服务器在线扩容。支持相同内容的文件只保存一份,节约磁盘空间。

       FastDFS没有官网。但是作者余庆(happy_fish100)担任chinaunix中FastDFS板块版主。并且会不定期更新板块中内容。

论坛
如果你要下载的话,就点击这里
安装点这里

关于角色问题

       FastDFS通常有三种角色。他们分别是 Client:客户端、Tracker Server:跟踪服务器、Storage Server:存储服务器

       Client客户端的话,它主要是Java语言编写的项目

       Tracker Server跟踪服务器,就主要做调度工作,在访问上起负载均衡的作用。在内存中记录集群中group和storage server的状态信息,是连接Client和Storage server的枢纽。

       而Storage Server存储服务器,主要就是把文件和文件属性(meta data)都保存到存储服务器上

架构分析

       当只有两个角色: tracker server和storage server的时候,则不需要存储文件索引信息。

       在FastDFS中所有服务器都是对等的,不存在Master-Slave关系。

       它们存储服务器通常采用分组方式,同组内存储服务器上的文件完全相同(RAID 1)

       而不同组的storage server之间不会相互通信。由storage server主动向tracker server报告状态信息,tracker server之间不会相互通信。

文件上传

添加依赖

  <dependencies>
        <dependency>
            <groupId>cn.bestwu</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.27</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
    </dependencies>

配置文件 (fastDFS.properties)

# 链接超时
fastdfs.connect_timeout_in_seconds=10
# 工作超时
fastdfs.network_timeout_in_seconds=30
# 字符集
fastdfs.charset=UTF-8
# tracker服务器地址,多个地址使用逗号','分隔。
fastdfs.tracker_servers=192.168.147.128:22122
# 和配合文件/etc/fdfs/tracker.conf中的http.server_port配置完全相同
fastdfs.http_tracker_http_port=8080

代码实现

注意:运行之前记得先启动服务

扫描二维码关注公众号,回复: 11587036 查看本文章

参考命令: service fdfs_trackerd start 、 service fdfs_storaged start

检查防火墙状态: service firewalld status

如果没关闭,就最好关闭防火墙: service firewalld stop

public class Test {
    //文件路径
    private static String dirPath = "C:\\Users\\36961\\Desktop\\desk_picture\\";
    public static void main(String[] args) throws IOException, MyException {
        upload();
    }
    //上传
    public static void upload() throws IOException, MyException {
        //加载配置文件,内容是tracker的ip和端口。还有链接的设置,如:超时
        //fastDFS的Java客户端提供了两种文件配置的格式:一种是conf,一种是properties
        Properties properties = new Properties();
        properties.load(Test.class.getClassLoader().getResourceAsStream("fastDFS.properties"));
        ClientGlobal.initByProperties(properties);
        //初始化客户端对象 StorageClient,存储客户端
        TrackerClient tracker = new TrackerClient();
        TrackerServer server = tracker.getConnection();
        StorageServer storage = tracker.getStoreStorage(server);
        StorageClient storageClient = new StorageClient(server,storage);
        //文件上传
        //读取文件字节内容到一个字节数组中,一个文件必须完整的存在一个数组中
        FileInputStream fileInputStream = new FileInputStream(dirPath + "time.png");
        //根据文件的字节长度.创建一个等长的数组
        byte[]buf = new byte[fileInputStream.available()];
        //把文件的内容完整的读取到数组中
        fileInputStream.read(buf,0,buf.length);
        //元数据,有使用者自定义,是名值对形式存在的数组。如文件名=time.png,文件长度=6666等
        NameValuePair[] valuePair = new NameValuePair[]{
                new NameValuePair("name","time.png")
        };
        //上传文件.返回一个字符串数组长度为2。0下标代表组名,1下标代表文件路径和文件名
        String[]result = storageClient.upload_file(buf,".png",valuePair);
        //处理上传结果
        System.out.println("result[0] = " + result[0]);
        System.out.println("result[1] = " + result[1]);
    }
}

       刚才的那种写法是比较原始的,复用性不高。所以我们肯定是要封装一个工具类的

代码修改

FastDfsUtil(工具)
public class FastDfsUtil {
    private FastDfsUtil(){}
    private static final Properties properties = new Properties();
    private static StorageClient storageClient;
    static{
        try {
            properties.load(Test.class.getClassLoader().getResourceAsStream("fastDFS.properties"));
            ClientGlobal.initByProperties(properties);
            // 初始化客户端对象。 StorageClient,存储客户端。
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient = new StorageClient(trackerServer, storageServer);
        }catch (Exception e){
            e.printStackTrace();
            // 初始化代码块异常,抛出错误,停止虚拟机。
            throw new ExceptionInInitializerError(e);
        }
    }

    // 上传文件
    public static String uploadFile(byte[] datas, String extName, NameValuePair[] nvps){
        try {
            String[] result = storageClient.upload_file(datas, extName, nvps);
            String path = result[0] + "/" + result[1];
            return path;
        }catch (Exception e){
            e.printStackTrace();
            // 上传失败
            return null;
        }
    }
}
Test类
public class Test {
    //文件路径
    private static String dirPath = "C:\\Users\\36961\\Desktop\\desk_picture\\";
    public static void main(String[] args) throws IOException, MyException {
        upload();
    }
    //上传
    public static void upload() throws IOException, MyException {
        FileInputStream in = new FileInputStream(dirPath+"time.png");
        int length = in.available();
        byte[] datas = new byte[length];
        in.read(datas, 0, length);
        NameValuePair[] nvps = new NameValuePair[]{
                new NameValuePair("name", "time.png"),
                new NameValuePair("length", length+"")
        };
        String result = FastDfsUtil.uploadFile(datas, "png", nvps);
        System.out.println(result);
    }
}

       这样一来就方便多了~

查看上传的文件(本人刚才操作的时候上传了三次。。。)

参考命令: cd /usr/local/fastdfs/storage/store/data/00/00 (以具体路径为准)

在这里插入图片描述

文件下载

修改FastDfsUtil工具类

  //下载文件
    public static byte[] download(String group, String path){
        try {
            return storageClient.download_file(group, path);
        }catch(Exception e){
            e.printStackTrace();
            // 下载失败
            return null;
        }
    }

    // 根据组名和文件信息查询元数据数组
    public static NameValuePair[] getMetaDatas(String group, String path){
        try {
            return storageClient.get_metadata(group, path);
        }catch (Exception e){
            e.printStackTrace();
            // 获取元数据失败
            return null;
        }
    }

Test类

public static void download() throws IOException {
        String grop = "group1";
        //这个文件名是刚刚上传的时候,通过Println打印的结果而得到的
        //如果想灵活一点,可以考虑使用变量来存储返回结果
        //主要是为了更好理解才这么写
        String path = "M00/00/00/wKiTgF8rseGAI7kMAAQPXweodas397.png";
        NameValuePair[] nameValuePair = FastDfsUtil.getMetaDatas(grop,path);
        byte[]buf = FastDfsUtil.download(grop,path);
        String localFileName = "";
        for(NameValuePair nvp : nameValuePair){
            if(nvp.getName().equals("name")){
                // 文件命名
                localFileName = nvp.getValue();
            }
        }
        if("".equals(localFileName)){
            // 元数据中没有文件名,设置文件名为随机命名
            localFileName = UUID.randomUUID().toString() + path.substring(path.lastIndexOf(".")+1);
        }
        FileOutputStream out = new FileOutputStream("D:\\"+localFileName);
        // 存储文件
        out.write(buf, 0, buf.length);
        out.flush(); // 可以省略,关闭流的时候,自动刷新缓冲区。
        out.close();
    }

文件删除

FastDfsUtil工具类
  /**
     * 删除文件。注意,删除FastDFS管理的文件,一定要使用客户端API完成。
     * 直接在XShell中使用rm命令删除文件,会破坏FastDFS对文件的管理逻辑。
     * 因为,通过客户端API删除的文件,Storage服务器会上报信息给Tracker。
     * 直接rm删除文件,没有上报过程,再下载或查看文件的时候,会有资源找不到错误。
     */
    public static boolean delete(String group, String path){
        try {
            int stat = storageClient.delete_file(group, path);
            return stat == 0;
        }catch (Exception e){
            e.printStackTrace();
            // 删除失败
            return false;
        }
    }
Test类
    //删除
    public static void delete() throws Exception {
        String group = "group1";
        String path = "M00/00/00/wKiTgF8rseGAI7kMAAQPXweodas397.png";
        boolean flag = FastDfsUtil.delete(group, path);
        System.out.println(flag ? "删除成功" : "删除失败");
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41424688/article/details/107837110