传统文件系统
文件下载
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.NET.URLEncoder; @WebServlet("/downFile") public class downFileInClientServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1、获取让浏览器下载的文件路径 String FileRealPath = "D:\JavaTrainStudy\servlet\out\production\study06-httpServletResponse\loginbg.png"; // 2、告知浏览器要下载的文件名是什么? String fileName = FileRealPath.substring( FileRealPath.lastIndexOf("\") + 1 ); // 3、让浏览器支持文件下载 // Content-Disposition这个就是让浏览器支持文件下载 // URLEncoder.encode( String s , String enc ) 是为了以防文件名是中文名,这样就设置编码格式了,让浏览器能够解析这个中文文件名 resp.setHeader("Content-Disposition" , "attachment ; filename=" + URLEncoder.encode(fileName , "utf-8")); // 4、获取输入、输出流对象 并 把服务器中的文件输出到浏览器上 FileInputStream fis = new FileInputStream( FileRealPath ); ServletOutputStream os = resp.getOutputStream(); // 创建缓冲区 int len = 0 ; byte[] buffer = new byte[1024]; while ( ( len = fis.read( buffer ) ) > 0 ){ os.write( buffer , 0 , len); } // 5、关闭流管道 if ( os != null ){ os.close(); } if ( fis != null ){ fis.close(); } } }
分布式文件系统
补充:常见的分布式文件系统
yum install gcc libevent libevent-devel -y
tar -zxvf libfastcommon-1.0.36.tar.gz
./make.sh # 当然:可以把命令进行合并 执行如下命令 就是编译并安装./make.sh && ./make.sh install
./make.sh install
tar -zxvf fastdfs-5.11.tar.gz
./make.sh # 一样的可以用组合命令 即:编译并安装./make.sh && ./make.sh install
./make.sh install
cd /usr/bin
cd /etc/fdfs
# 供Nginx访问使用cp http.conf /etc/fdfs # 供nginx访问使用cp mime.types /etc/fdfs
/etc/fdfs mv storage.conf.sample ./storage.conf mv tracker.conf.sample ./tracker.conf
vim tracker.conf # 搜索此配置/base_path # 改成的值,也可以自定义自己的目录( 注意:需要保证这个目录必须存在,没存在那就需要创建 )base_path=/opt/fastdfs/tracker
# storage存储数据目录base_path=/opt/fastdfs/storage # 真正存放文件的目录store_path0=/opt/fastdfs/storage/files # 注册当前存储节点的跟踪器地址tracker_server=服务器ip:22122
mkdir -p /opt/fastdfs/tracker mkdir -p /opt/fastdfs/storage mkdir -p /opt/fastdfs/storage/files
# 启动tracker 要想看fdfs_trackerd的命令用法,那直接输入fdfs_trackerd就可以弹出其用法了# 如:要关闭tracker,则命令为:fdfs_trackerd /etc/fdfs/tracker.conf stop# 开启 | 重启就是把stop改成start | restart即可fdfs_trackerd /etc/fdfs/tracker.conf # 启动storagefdfs_storaged /etc/fdfs/storage.conf
ps -ef | grep fdfs
# 查看日志文件是否有报ERRORcat /opt/fastdfs/storage/logs/storage.log
ERROR - file: storage_ip_changed_dealer.c, line: 180, connect to tracker server 服务器ip:22122 fail, errno: 110, error info: Connection timed out 即:链接超时
# 开放22122端口firewall-cmd --zone=public --add-port=22122/tcp --permanent # 重启防火墙systemctl restart firewalld.service # 当然:要是云服务器的话,直接在web管理界面中添加规则( 开放22122端口 ) 即可
cd /opt/fastdfs/storage/files/data
# 注意:这个目录也要保证存在,不存在就是创建 mkdir -p /opt/fastdfs/clientbase_path=/opt/fastdfs/client tracker_server=自己服务器ip:22122
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers# <> 表示必填 # 因此:在测试中,文件上传的指令为:fdfs_test /etc/fdfs/client.conf upload /root/hello-fastdfs.txt
# 开放23000端口firewall-cmd --zone=public --add-port=23000/tcp --permanent # 刷新防火墙systemctl restart firewalld.service
This is FastDFS client test program v5.11 Copyright (C) 2008, Happy Fish / YuQing FastDFS may be copied only under the terms of the GNU GeneralPublic License V3, which may be found in the FastDFS source kit. # 这个是说访问fastdfs的主页网址 - 目前还不能访问,需要后面弄Please visit the FastDFS Home Page http://www.csource.org/ for more detail. # 这是配置的client.conf中的信息[2022-06-01 10:17:07] DEBUG - base_path=/opt/fastdfs/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0 tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=162.14.66.60, port=23000 group_name=group1, ip_addr=162.14.66.60, port=23000storage_upload_by_filename# 重要的信息在这里group_name、remote_filename# group_name就是组名,在前面配置中见过它,就是说的文件系统 和 数据备份这二者的组合名# remote_filename 远程文件名 这是关键中的关键,告知你:文件保存到那里去了group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txtsource ip address: 10.0.0.16file timestamp=2022-06-01 10:17:07file size=641file crc32=1141168436# 下面这个URL地址很重要,就是去浏览器访问上传的这个文件资源的地址,但是:目前还不可以访问,因为没有配置Nginxexample file url: http://162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txtstorage_upload_slave_by_filenamegroup_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txtsource ip address: 10.0.0.16file timestamp=2022-06-01 10:17:07file size=641file crc32=1141168436example file url: http://162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt
remote_filename=M00/00/00/ M00 指的是:/opt/fastdfs/storage/files/data 就是前面去看默认创建文件数( 256 * 256 )的位置,跟前面的配置有关啊 00/00/ 指的就是:/opt/fastdfs/storage/files/data目录下的00子目录,这里面的00目录 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt 指的是:保存的文件名 fastdfs会重新生成文件名,以防的就是同名文件,造成附件覆盖的问题
# _big 就是数据备份文件# _m 就是meta data文件,即:文件属性文件( 文件名、文件后缀、文件大小..... )-rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m # 这两个就是文件系统中的文件-rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt 和 文件系统中的CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt存的内容是一样的 # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m 和 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m这两个备份文件也是相应的
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers# <> 表示必填
# 变成下载的命令,然后使用此命令查看完整命令即可fdfs_test /etc/fdfs/client.conf download # 根据执行上面的命令,得到文件下载的语法fdfs_test <config_file> download <group_name> <remote_filename> # 那么想要下载刚刚上传的文件,执行如下的命令即可fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt# 其中:group 和 remote_filename都在前面上传时见过了# 注:这个下载是下载到当前所在目录的位置 # 同理:就可以得到文件删除的命令了fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt
# nginx安装目录/usr/local/nginx_fdfs # fastdfs-nginx模块的src目录/usr/local/fastdfs-nginx-module-master/src
# 进入nginx安装目录cd nginx_fdfs # 执行模块配置 # prefix 就是前面让记住的nginx安装目录 add-module就是fastdfs-nginx模块的src目录./configure --prefix=/usr/local/nginx_fdfs --add-module=/usr/local/fastdfs-nginx-module-master/src
# 在安装的nginx目录下载执行下述命令make & make install
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
cp /usr/local/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs
vim mod_fastdfs.conf # 修改内容如下:# 这个目录要保证存在,不存在就要配置好了创建它 mkdir -p /opt/fastdfs/nginx_modbase_path=/opt/fastdfs/nginx_mod tracker_server=自己服务器ip:22122 # 访问地址是否带上组名url_have_group_name = true store_path0=/opt/fastdfs/storage/files
# 编辑nginx.conf文件vim /usr/local/nginx_fdfs/conf/nginx.conf # 配置内容location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module; } # 解读:ngx_fastdfs_module# 这个指令不是Nginx本身提供的,是扩展模块提供的,根据这个指令找到FastDFS提供的Nginx模块配置文件,然后找到Tracker,最终找到Stroager
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t /usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf # 保险起见,查看nginx是否启动成功ps -ef | grep nginx
nobody 3895 3894 0 15:45 ? 00:00:00 nginx: worker process
cd /usr/local/nginx_fdfs/logs # 还有一份日志中也可能出现错误信息cd /opt/fastdfs/nginx_mod
tracker_server=服务器ip:22122
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : UploadFile * @description : 该类功能 FastDFS文件上传 * @packageName : com.zixieqing */ public class UploadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、创建tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 - 这个对象就是用来上传文件、下载文件、删除文件的 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、上传文件 /* 这里有两个API需要了解 String[] upload_file(byte[] file_buff, int offset, int length, String file_ext_name, NameValuePair[] meta_list) 这个API常用来web中上传文件的 参数1 file_buff、文件字节 offset、length、从文件的那个位置开始上传,截止位置 参数4 file_ext_name、文件后缀 参数5 meta_list、文件的属性文件 String[] upload_file(String local_filename, String file_ext_name, NameValuePair[] meta_list) 这个API是上传本地文件的 参数1 local_filename、本地文件的绝对路径 参数2 file_ext_name、文件后缀名 参数3 meta_list、文件的属性文件,linux1中的哪个meta data,一般都不传 上述这两个API,注意返回值,这个String[] 很重要,就是涉及到linux中的那个组名group 和 远程文件名remote_filename,这个group和remote_fileName一般是存在数据库中的 */ String[] result = storageClient.upload_file("C:\Users\ZiXieQing\Desktop\图库\19.jpg", "jpg", null); // 7、验证一下 for (String data : result) { System.out.println("data = " + data); } } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DownloadFile * @description : 该类功能 fastDFS文件下载 * @packageName : com.zixieqing */ public class DownloadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、下载文件 /* 这里需要知道两个API byte[] download_file(String group_name, String remote_filename) 这个API常用于web操作 int download_file(String group_name, String remote_filename, String local_filename) 这个API是把文件下载到本地磁盘中 这个API的返回值结果很重要 */ String group = "group1"; String remoteFileName = "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"; // 存入本地磁盘路径+存入磁盘的文件名 String localFileName = "d:/靓妹.jpg"; // 只有返回值是0才表示下载成功,否则只要是其他数字都是下载失败( 其他数字有可能是组名错了,远程文件名错了........ int result = storageClient.download_file(group, remoteFileName, localFileName); // 7、验证 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DeleteFile * @description : 该类功能 FastDFS删除文件 * @packageName : com.zixieqing */ public class DeleteFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、获取storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、执行文件删除 /* int delete_file(String group_name, String remote_filename) 参数1 group_name、组名 参数2 remote_filename、远程文件名 */ // 一样的,返回值是0就表示成功,其他都是删除失败 int result = storageClient.delete_file("group", "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"); // 7、验证一下 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); }finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
文章来自
https://www.cnblogs.com/xiegongzi/p/16330724.html