本人已参与【新人创作礼】活动,一起开启掘金创作之路。 本文首发于CSDN
hello,大家好,我是wangzirui32,今天来教大家如何使用Flask框架实现一个文件共享服务器。
开始学习吧!\
学习目录
前言
在工作中,我们时不时会遇到多个人同时向我们需求同一份文件,而手工一个一个发电子邮件,太累,所以诞生了这款文件共享服务器。这款服务器拥有上传文件和下载文件的功能,开启后,整个局域网内连接的设备,都能访问到这个文件共享服务器,并使用它的所有功能。
1. 项目架构
项目结构如下:
files文件夹下有三个测试文件,templates里准备了四个HTML模板。
2. app.py编写
代码奉上:
from flask import Flask
from flask import render_template, send_from_directory, request, redirect, url_for
import os
import time
# 全局变量 共享的文件夹路径 可以根据需求更改
DIRECTORY_PATH = r"C:\Users\wangzirui32\Desktop\Flask局域网文件共享\files"
# 创建项目
app = Flask(__name__)
app.config['SECURE_KEY'] = 'askydiqyddiudhiudiwuhdhdyjqoijd'
# 获取文件信息的函数
def get_files_data():
files = []
for i in os.listdir(DIRECTORY_PATH):
if len(i.split(".")) == 1: # 判断此文件是否为一个文件夹
continue
# 拼接路径
file_path = DIRECTORY_PATH+"/"+i
name = i
size = os.path.getsize(file_path) # 获取文件大小
ctime = time.localtime(os.path.getctime(file_path)) # 格式化创建当时的时间戳
# 列表信息
files.append({
"name": name,
"size": size,
"ctime": "{}年{}月{}日".format(ctime.tm_year, ctime.tm_mon, ctime.tm_mday), # 拼接年月日信息
})
return files
@app.route("/")
def index():
"""共享文件主页"""
return render_template("index.html", files=get_files_data())
@app.route("/download_file/<filename>")
def file_content(filename):
"""下载文件的URL"""
if filename in os.listdir(DIRECTORY_PATH): # 如果需求下载文件存在
# 发送文件 参数:文件夹路径,文件路径,文件名
return send_from_directory(DIRECTORY_PATH, DIRECTORY_PATH+"/"+filename, filename)
else:
# 否则返回错误页面
return render_template("download_error.html", filename=filename)
@app.route("/upload_file", methods=['GET', 'POST'])
def upload():
"""上传文件的URL 支持GET/POST请求"""
if request.method == "POST":
# 获取文件 拼接存储路径并保存
upload_file = request.files.get("upload_file")
upload_file.save(os.path.join(DIRECTORY_PATH, upload_file.filename))
# 返回上传成功的模板
return render_template("upload_ok.html", filename=upload_file.filename)
# 上传的网页
return render_template("upload.html")
if __name__ == '__main__':
# 在局域网上开启端口
app.run(host="0.0.0.0", port="8000")
服务器在本机上开了一个端口,局域网内的所有已经连接的设备都可以访问。
3. HTML模板编写
HTML的模板编写稍微复杂一点。
3.1 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FLASK局域网文件共享</title>
<!-- 标签的CSS样式设置 看不懂没关系 只要知道它布置了HTML页面的样式就行-->
<style>
body {
padding: 20px;
}
.files-table {
border-radius: 10px;
width: 1000px;
border: 3px solid blue;
background-color: lightyellow;
}
.files-table td {
width: 150px;
height: 20px;
text-align: center;
font-size: 25px;
}
.td-name {
color: coral;
}
.td-name a, a:link, a:visited {
color: coral;
}
.td-size {
color: dodgerblue;
}
.td-ctime {
color: goldenrod;
}
h4 a {
text-decoration: none;
border: 3px solid cyan;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>FLASK局域网文件共享</h1>
<table class="files-table" border="1">
<tr><!-- 表头 -->
<td class="td-name">文件名</td>
<td class="td-size">大小</td>
<td class="td-ctime">创建日期</td>
</tr>
<!-- 将传上来的files进行遍历 输出HTML标签 -->
{% for file in files %}
<tr>
<td class="td-name"><a href="/download_file/{{file.name}}">{{file.name}}</a></td>
<td class="td-size">{{file.size}} B</td>
<td class="td-ctime">{{file.ctime}}</td>
</tr>
{% endfor %}
</table>
<h4><a href="/upload_file">----->去上传文件</a></h4>
</body>
</html>
3.2 upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传文件</title>
<style>
body {
padding: 10px;
}
h1 {
color: orange;
}
form {
border-radius: 10px;
border: 5px solid red;
width: 400px;
height: 145px;
background-color:lightskyblue;
}
form h3 {
padding-left: 10px;
}
form input {
color: coral;
}
form button {
position: relative;
width: 100px;
height: 40px;
color: deepskyblue;
font-size: 25px;
left: 10px;
}
</style>
</head>
<body>
<h1>上传文件</h1>
<!-- enctype="multipart/form-data" 设置表单的文件以二进制方式上传 就可以上传多种不同的文件 -->
<form name="upload_form" action="#" method="post" enctype="multipart/form-data">
<h3>请选择上传的文件:<input type="file" name="upload_file" /></h4>
<button type="submit">提交</button>
</form>
</body>
</html>
3.3 download_error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件下载错误</title>
</head>
<body>
<h3>您所访问的"{{filename}}"文件并不存在!请点击<a href="/">链接</a>回到主页!</h3>
</body>
</html>
3.4 upload_ok.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传成功提示</title>
</head>
<body>
<h2>您所上传的"{{filename}}"已经存储到了服务器中,请前往<a href="/">主页</a>进行其他操作!</h2>
</body>
</html>
4. 效果展示
运行app.py中的代码,并访问主页(http://你的局域网IP地址:8000):
点击"myFile.txt",可以看到,成功读取文件内容:
将浏览器URL里的"myFile.txt"改为"myFile",测试下载错误页面:
接下来,访问文件上传页面,选择文件,进行上传:
点击“提交”,可以看到:
files文件夹也变成了:
这个项目还可以拓展,如增加一个上传错误的页面,或者增加一个用户系统等等。
好了,今天的课程就到这里,我是wangzirui32,我们下次再见!