Python实现基于HDFS的云盘系统
一.云盘系统
云盘系统通过互联网为企业和个人提供信息的存储、读取、下载等服务。具有安全稳定、海量等特点。目前,云盘系统逐步走向成熟,特别是公有云盘能够向用户提供免费存储,,离线下载,文件智能分类等功能。随着互联网的不断普及,用户存储在云盘上的数据量越来越大,数据类型页越来越多样化,不仅有传统的文本文件,二进制文件,还有视频,音频,图像,图片等。这些数据不仅类型繁多,而且数据量普遍庞大。例如,一个视频文件可能高达几个G甚至几十个G。因此充分利用大数据平台的优势,可以为云盘提供一套适合上述特点的底层环境。
本题目要求开发一个基于HDFS的云盘系统来实现云盘的基本数据存储和访问功能。
二.功能需求
2.1.用户管理
用户的注册,登录,退出。注册成功时需要将用户信息写入数据库,并在HDFS中建立用户的专属目录。
2.2.文件管理
提供文件上传,下载,浏览,删除等功能。提供目录的管理,可以创建目录,复制或移动文件或目录到指定目录下面;可以删除目录。删除目录时需要给出提示。提供文件搜索功能。
2.3.界面设计
为系统设计并实现主界面,基于窗口或基于浏览器均可。所有操作均在人机交互界面中完成。
三.用户代码
引用所需要 用到的库函数
from hdfs import *
import os
import os.path
import tkinter.filedialog
import tkinter as tk
from PIL import Image,ImageTk
import tkinter.messagebox
import pickle
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
from tkinter import ttk
import time
import sys
from pyhdfs import HdfsClient
from tkinter import filedialog
from tkinter.filedialog import askdirectory
from pathlib import Path
from hdfs3 import HDFileSystem
Client—创建集群链接
client=Client('http://47.112.220.22:9870')
3.1 用户登录
登录函数python代码:
def usr_log_in():
#输入框获取用户名密码
usr_name=var_usr_name.get()
usr_pwd=var_usr_pwd.get()
#从本地字典获取用户信息,如果没有则新建本地数据库
try:
with open('usr_info.pickle','rb') as usr_file:
usrs_info=pickle.load(usr_file)
except FileNotFoundError:
with open('usr_info.pickle','wb') as usr_file:
usrs_info={'admin':'admin'}
pickle.dump(usrs_info,usr_file)
#判断用户名和密码是否匹配
if usr_name in usrs_info:
if usr_pwd == usrs_info[usr_name]:
str=tk.messagebox.showinfo(title='welcome',
message='欢迎您:'+usr_name)
#文件窗口
if str=='ok':
window.destroy()
main_face(usr_name)
else:
tk.messagebox.showerror(message='密码错误')
#用户名密码不能为空
elif usr_name=='' or usr_pwd=='' :
tk.messagebox.showerror(message='用户名或密码为空')
#不在数据库中弹出是否注册的框
else:
is_signup=tk.messagebox.askyesno('欢迎','您还没有注册,是否现在注册')
if is_signup:
usr_sign_up()
3.2 用户注册
注册函数python代码:
def usr_sign_up():
#确认注册时的相应函数
def signtowcg():
#获取输入框内的内容
nn=new_name.get()
np=new_pwd.get()
npf=new_pwd_confirm.get()
#本地加载已有用户信息,如果没有则已有用户信息为空
try:
with open('usr_info.pickle','rb') as usr_file:
exist_usr_info=pickle.load(usr_file)
except FileNotFoundError:
exist_usr_info={}
#检查用户名存在、密码为空、密码前后不一致
if nn in exist_usr_info:
tk.messagebox.showerror('错误','用户名已存在')
elif np =='' or nn=='':
tk.messagebox.showerror('错误','用户名或密码为空')
elif np !=npf:
tk.messagebox.showerror('错误','密码前后不一致')
#注册信息没有问题则将用户名密码写入数据库
else:
exist_usr_info[nn]=np
with open('usr_info.pickle','wb') as usr_file:
pickle.dump(exist_usr_info,usr_file)
str2=tk.messagebox.showinfo('欢迎','注册成功')
if str2=="ok":
client.makedirs('/user/hadoop/cloudpan/'+new_name.get())
client.makedirs('/user/hadoop/cloudpan/'+new_name.get()+'/我的文档')
#注册成功关闭注册框
window_sign_up.destroy()
#新建注册界面
window_sign_up=tk.Toplevel(window)
window_sign_up.geometry('350x200')
window_sign_up.title('注册')
#用户名变量及标签、输入框
new_name=tk.StringVar()
tk.Label(window_sign_up,text='用户名:').place(x=10,y=10)
tk.Entry(window_sign_up,textvariable=new_name).place(x=150,y=10)
#密码变量及标签、输入框
new_pwd=tk.StringVar()
tk.Label(window_sign_up,text='请输入密码:').place(x=10,y=50)
tk.Entry(window_sign_up,textvariable=new_pwd,show='*').place(x=150,y=50)
#重复密码变量及标签、输入框
new_pwd_confirm=tk.StringVar()
tk.Label(window_sign_up,text='请再次输入密码:').place(x=10,y=90)
tk.Entry(window_sign_up,textvariable=new_pwd_confirm,show='*').place(x=150,y=90)
#确认注册按钮及位置
bt_confirm_sign_up=tk.Button(window_sign_up,text='确认注册',
command=signtowcg)
bt_confirm_sign_up.place(x=150,y=130)
3.3 用户退出
推出函数python代码:
def usr_sign_quit():
window.destroy()
四.文件代码
4.1 上传打开本地窗口
上传打开本地窗口函数python代码:
def load_window():
root = tk.Tk()
root.withdraw()
path=filedialog.askopenfilename()
return path
4.2 下载并命名显示本地窗口
下载并命名显示本地窗口函数python代码:
#下载并命名显示本地窗口
def savefile_window():
root = tk.Tk()
root.withdraw()
name=filedialog.asksaveasfilename()
return name
4.3 下载文件
下载文件函数python代码:
# 下载文件
def get_from_hdfs(path):
address=savefile_window()#调用保存文件窗口
client.download(path,address)
4.4 移动文件
移动文件函数python代码:
def movefile(path,username):
for item in tree.selection():
entryedit = tk.Entry(frm)
entryedit.pack()
def move():
client.rename(path[-3],path[-2]+'/'+entryedit.get()+'/')
b1 = tk.Button(frm1,text="move",width=15,height=30,command=move)
b1.pack(padx=30,pady=10,side='right')
4.5 删除文件
删除文件函数python代码:
# 删除文件
def delete_file(path,username):
if path!=rootPath1: #操作非根目录
try:
client.delete(path)
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='操作成功!')
main_face(username)
except:
tk.messagebox.showinfo(title='提示', message='文件夹不为空!')
else:#提示根目录不能删除
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='此目录不能删除!')
main_face(username)
4.6 创建文件
创建文件函数python代码:
# 创建文件
def new_dir(path,username):
if(client.status(path)['type'] == 'DIRECTORY'):#如果是文件夹就执行
root=tk.Tk()
root.title('创建文件夹')
dir_name=tk.StringVar(root,value='')
tk.Label(root,text='名称:').place(x=10,y=10)
tk.Entry(root,textvariable=dir_name).place(x=30,y=10)
def get_dir_name():
dir_names = dir_name.get()
client.makedirs(path+'/'+dir_name.get(),permission=777)
root.destroy()
window.destroy()
root1 = tkinter.Tk()
root1.withdraw()
tk.messagebox.showinfo(title='提示', message='操作成功!')
main_face(username)
tk.Button(root,text='确定',command=get_dir_name).place(x=150,y=10)
else:#否则不执行
window.destroy()
root2 = tkinter.Tk()
root2.withdraw()
tk.messagebox.showinfo(title='提示', message='操作失败!')
main_face(username)
4.7 上传文件
上传文件函数python代码:
# 上传文件
def put_to_hdfs(path,username):
address=load_window()
if address=='':#点击取消之后执行
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='请选择文件!')
main_face(username)
else:#点击文件之后执行
filename=os.path.basename(address)
if filename in client.list(path[-2]):
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='文件已存在!')
main_face(username)
else:
if(client.status(path[-1])['type'] == 'DIRECTORY'): #上传到文件夹中
client.upload(path[-1],address)
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='操作成功!')
main_face(username)
else:#上传到根目录
client.upload(path[-2],address)
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='操作成功!')
main_face(username)
4.8 鼠标双击事件重命名
鼠标双击事件重命名函数python代码:
# 鼠标双击事件重命名
def newname(oldname,username):
for item in tree.selection():
entryedit = tk.Entry(frm)
entryedit.pack()
def save():
rename = entryedit.get()
if rename=='':#名字为空执行
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='名称为空!')
main_face(username)
else:#名字不为空执行
if rename in client.list(oldname[-2]): #名字已存在执行
window.destroy()
root = tkinter.Tk()
root.withdraw()
tk.messagebox.showinfo(title='提示', message='名称已存在!')
main_face(username)
else:#名字不存在执行
client.rename(oldname[-1],oldname[-2]+'/'+rename)
window.destroy()
root1 = tkinter.Tk()
root1.withdraw()
tk.messagebox.showinfo(title='提示', message='操作成功!')
main_face(username)
b = tk.Button(frm1,text="save",width=15,height=30,command=save)
b.pack(padx=30,pady=10,side='right')
4.9 右键菜单
右键菜单函数python代码:
#右键菜单
def button_menu(event):
for item in tree.selection():
item_values = tree.item(item, "values")
menu = tk.Menu(tree,tearoff=0)
menu.add_command(label="重命名",command=lambda:newname(item_values,username))
menu.add_command(label="删除",command=lambda:delete_file(item_values[-1],username))
menu.add_command(label="下载",command=lambda:get_from_hdfs(item_values[-1]))
menu.add_command(label="新建文件夹",command=lambda:new_dir(item_values[-2],username))
menu.add_command(label="新建到当前目录",command=lambda:new_dir(item_values[-1],username))
menu.add_command(label="上传",command=lambda:put_to_hdfs(item_values,username))
menu.add_command(label="移动",command=lambda:movefile(item_values,username))
def postmenu(event):
menu.post(event.x_root,event.y_root)
tree.bind('<Button-3>',postmenu)
五.代码下载
我已将代码上传至CSDN,对代码感兴趣的小伙伴,可以点击链接下载 HDFS.zip。