一、shutil模块

1、介绍

shutil模块是对os中文件操作的补充。--移动 复制 打包 压缩 解压

2、基本使用

1. shutil.copyfileobj(文件1, 文件2, 长度)
将文件1的数据覆盖copy给文件2,可以copy指定大小的内容
文件1和2都是文件对象,都需要打开后才能进行复制操作 import shutil f1 = open('testdir/1.txt', 'r', encoding='utf8')
f2 = open('testdir/2.txt', 'w', encoding='utf8') shutil.copyfileobj(f1, f2, length=1024) 2. shutil.copyfile(文件1,文件2)
不用打开文件,直接复制,实际上copyfile调用了copyfileobj import shutil # 1.txt必须要有,3.txt没有就创建,有就覆盖内容
shutil.copyfile('testdir/1.txt', 'testdir/3.txt') 3. shutil.copymode(文件1,文件2)
仅copy权限,不更改文件内容,组和用户 # 先看两个文件的权限
$ ls -l
-rw-r--r-- 1 Administrator 197121 5 1月 5 10:22 1.txt
-rwxr-xr-x 1 Administrator 197121 8 1月 5 10:24 2.txt # 运行命令
import shutil
shutil.copymode('testdir/1.txt', 'testdir/2.txt') #查看结果
$ ls -l
-rw-r--r-- 1 Administrator 197121 5 1月 5 10:22 1.txt
-rw-r--r-- 1 Administrator 197121 8 1月 5 10:24 2.txt 4. shutil.copystat(src,dst)
复制所有的状态信息,包括权限,组,用户,时间等 import shutil shutil.copystat('testdir/1.txt', 'testdir/2.txt') #查看结果(时间都变了)
$ ls -l
-rw-r--r-- 1 Administrator 197121 5 1月 5 10:22 1.txt
-rw-r--r-- 1 Administrator 197121 8 1月 5 10:22 2.txt 5. shutil.copy(src,dst)
复制文件的内容以及权限,先copyfile后copymode import shutil shutil.copy('testdir/1.txt', 'testdir/2.txt') 6. shutil.copy2(src,dst)
复制文件的内容以及文件的所有状态信息。先copyfile后copystat import shutil shutil.copy2('testdir/1.txt', 'testdir/2.txt') 7. shutil.copytree(src, dst)
递归的复制文件内容及状态信息(就是拷贝整个目录) import shutil shutil.copytree('testdir', 'testdir2') 结果
/testdir
$ ls -l
total 2
-rw-r--r-- 1 Administrator 197121 5 1月 5 10:22 1.txt
-rw-r--r-- 1 Administrator 197121 8 1月 5 10:22 2.txt testdir2
$ ls -l
total 2
-rw-r--r-- 1 Administrator 197121 5 1月 5 10:22 1.txt
-rw-r--r-- 1 Administrator 197121 8 1月 5 10:22 2.txt 8. shutil.rmtree(path)
递归地删除文件 import shutil shutil.rmtree('testdir2') 结果
testdir2目录还在,但是里面的文件全删了,也就是testdir2现在是一个空文件夹 9. shutil.move(src, dst)
递归的移动文件 import shutil shutil.move('3.txt', 'testdir') # 把3.txt移动到testdir这个文件夹下 10. make_archive(base_name, format, root_dir=None)
压缩打包
base_name:压缩打包后的文件名或者路径名
format: 压缩或者打包格式 "zip", "tar", "bztar"or "gztar"
root_dir : 将哪个目录或者文件打包(也就是源文件) import shutil shutil.make_archive('E:/MyProjects/test', 'zip', root_dir='testdir') 把testdir这个目录(文件也行)压缩到E:/MyProjects目录下,压缩后的名字为test,格式为zip,
也就是说压缩完成后,在E:/MyProjects下会生成一个test.zip包 11. 解压
shutil 对压缩包的处理是调用 ZipFile模块来进行的 11-1、zipfile 压缩解压
# 压缩
# 把testdir文件夹下的1.txt和2.txt压缩到E:/MyProjects/test1.zip
z = zipfile.ZipFile('E:/MyProjects/test1.zip', 'w') # 可以用 a 模块,那么zip包里面可以追加内容 z.write('testdir/1.txt')
z.write('testdir/2.txt')
z.close() # 解压
import zipfile z = zipfile.ZipFile('E:/MyProjects/test1.zip', 'r') z.extractall('E:/MyProjects/test111')#将E:/MyProjects/test1.zip解压到E:/MyProjects/test111目录下 # 高级应用
zipfile.is_zipfile(filename)
判断一个文件是不是压缩文件 ZipFile.namelist()
返回文件列表 ZipFile.open(name[, mode[, password]])
打开压缩文档中的某个文件 11-2、使用shutil的内在方法解压
shutil._unpack_zipfile(file, path) import shutil shutil._unpack_zipfile('E:/MyProjects/test1.zip', 'E:/MyProjects/test1')
# 把E:/MyProjects/test1.zip这个zip包解压到E:/MyProjects/test1文件夹下

二、上传Demo

1、socket上传文件

import json
import struct
import socketserver
import operate_handler class MyFTP(socketserver.BaseRequestHandler):
def handle(self):
conn = self.request
length = conn.recv(4)
length = struct.unpack('i',length)[0]
operate = (conn.recv(length)).decode('utf-8')
operate_dic = json.loads(operate)
opt = operate_dic['operate']
usr = operate_dic['user']
print(opt,usr)
getattr(operate_handler,opt)(conn,usr) socketserver.TCPServer.allow_reuse_address = True
server = socketserver.ThreadingTCPServer(('127.0.0.1',9000),MyFTP)
server.serve_forever()

1. server.py

import os
import json
import struct base_path = r'E:\PythonProject\ftp\server\root' def upload(conn,usr):
fileinfo_len = conn.recv(4)
fileinfo_len = struct.unpack('i',fileinfo_len)[0]
fileinfo = (conn.recv(fileinfo_len)).decode('utf-8')
fileinfo = json.loads(fileinfo)
file_path = os.path.join(base_path,usr,fileinfo['filename'])
file_path = os.path.abspath(file_path)
with open(file_path,'wb') as f:
while fileinfo['filesize']:
content = conn.recv(20480)
fileinfo['filesize'] -= len(content)
f.write(content)
print('接收完毕')

2. operate_handler.py

import os
import json
import struct
import socket # 发送信息
def my_send(sk,operate_info):
b_optinfo = (json.dumps(operate_info)).encode('utf-8')
num = struct.pack('i',len(b_optinfo))
sk.send(num)
sk.send(b_optinfo) sk = socket.socket()
sk.connect(('127.0.0.1',9000)) # [登录,注册,退出] # 要进行的操作
operate_info = {'operate':'upload','user':'xiaoming'}
my_send(sk,operate_info) # 选择一个文发送到server端
file_path = r'F:\电影\电影\荒野生存.mp4' # 发送文件信息
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
file_info = {'filename':file_name,'filesize':file_size}
my_send(sk,file_info) # server端接收写入
with open(file_path,'rb') as f:
while file_size:
content = f.read(20480)
file_size -= len(content)
sk.send(content)
print('上传完毕')
sk.close()

3. client.py

2、Django中使用form表单上传文件

from django.shortcuts import render, HttpResponse, redirect
from django import views
import os, time
from django.conf import settings class UploadView(views.View): def get(self, request):
return render(request, 'upload.html') def post(self, request):
# 文本类型的数据用request.POST获取,键对应的值是字符串类型
print(request.POST)
# 文件类型的数据用request.FILES获取,键对应的值是类的对象
print(request.FILES)
# 获取文件对象(是一大串bytes类型的字节码)
file_obj = request.FILES.get('file')
# 文件对象有个内置的属性name,用于获取接收到的文件名
filename = file_obj.name
# 判断本地是否有同名的文件存在
if os.path.exists(os.path.join(settings.BASE_DIR, filename)):
# 重命名文件
prefix_name = filename.split('.')[0] # 前缀
suffix_name = filename.split('.')[1] # 后缀
filename = prefix_name + str(time.time()) + suffix_name
# 建一个同名的文件接收上传的数据
# with open(filename, 'wb') as f:
# for i in file_obj:
# f.write(i) # 跟上面的方法是一样的,只不过chunks是一个内置的方法,可以设置每次接收的数据大小
with open(filename, 'wb') as f:
for chunk in file_obj.chunks(chunk_size=1024):
f.write(chunk) return HttpResponse('收到啦!')

1. views.py

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-type" charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Upload</title>
</head> <body> <form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p><input type="text" name="username"></p>
<p><input type="file" name="file"></p>
<p><input type="submit"></p>
</form> </body>
</html>

2. HTML代码

3、ajax文件上传

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Upload</title>
</head>
<body> {% csrf_token %} <h1>上传文件</h1>
<div>
<input type="file" id="f1">
<button id="b1"> 上传</button>
</div>
<span style="color: red" id="s1"></span> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$('#b1').click(function () {
// 取到要上传的文件数据,存到一个对象中
var fdObj = new FormData();
fdObj.append('xx', $('#f1')[0].files[0]);
// 在请求的数据中添加csrftokrn
var csrfToken = $('[name="csrfmiddlewaretoken"]').val();
fdObj.append('csrfmiddlewaretoken', csrfToken);
// 发ajax请求
$.ajax({
url: '/upload/',
type: 'post',
data: fdObj,
processData: false, // 告诉jQuery不要处理我上传的数据
contentType: false, // 告诉jQuery不要设置请求的文件类型,这两个参数相当于enctype="multipart/form-data"
success: function (res) {
$("#s1").text(res);
}
})
})
</script>
</body>
</html>

1. HTML代码

class UploadView(views.View):
def get(self, request):
return render(request, 'upload.html') def post(self, request):
file_obj = request.FILES.get('xx')
file_name = file_obj.name
with open(file_name, 'wb') as f:
for c in file_obj.chunks():
f.write(c)
return HttpResponse('上传成功!')

2. views.py

4、Flask的文件上传并统计代码行数

"""
app.config.root_path: 项目的根路径
os.walk:
遍历你给的路径下的所有文件(会递归遍历)
每次循环的根文件夹的路径,文件夹的名字组成的列表,和文件组成的列表
dirpath, dirnames, filenames
zipfile: 压缩解压文件的模块
shutil: 也是压缩解压文件的模块,还能移动啥的
""" from flask import Blueprint, request, render_template
from flask import current_app as app
import shutil
from uploadCode.models import CodeRecord
from uploadCode import db
import os
import time uploadBlue = Blueprint('uploadBlue', __name__) # zip包上传
@uploadBlue.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == "GET":
return render_template("upload.html", error="")
# 先获取前端传过来的文件
file = request.files.get("zip_file")
# 判断是否是zip包
zip_file_type = file.filename.rsplit(".", 1)
if zip_file_type[-1] != "zip":
return render_template("upload.html", error="文件必须是zip包")
# 解压路径
upload_path = os.path.join(app.config.root_path, "files", zip_file_type[0]+str(time.time()))
print(upload_path)
# 解压前端传过来的文件file到upload_path这个路径
shutil._unpack_zipfile(file, upload_path)
# 遍历保存的文件夹得到所有.py文件
file_list = []
for (dirpath, dirnames, filenames) in os.walk(upload_path):
for filename in filenames:
file_type = filename.rsplit(".", 1)
if file_type[-1] != "py":
continue
file_path = os.path.join(dirpath, filename)
file_list.append(file_path)
# 打开每个文件读取行数
sum_num = 0
for path in file_list:
with open(path, mode="rb") as f:
for line in f:
if line.strip().startswith(b"#"):
continue
sum_num += 1
# 得到总行数去保存数据库
return str(sum_num)

1. upload.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
请上传你的代码: <input type="file" name="zip_file">
<button type="submit">提交</button>
{{error}}
</form> </body>
</html>

2. HTML代码

shutil模块和几种文件上传Demo的更多相关文章

  1. Django之三种文件上传

    方式一: 通过form表单提交到后台 前端: <!DOCTYPE html> <html lang="en"> <head> <meta ...

  2. 基于python的selenium两种文件上传操作

    方法一.input标签上传     如果是input标签,可以直接输入路径,那么可以直接调用send_keys输入路径,这里不做过多赘述,前文有相关操作方法. 方法二.非input标签上传 这种上传方 ...

  3. node.js系列(实例):原生node.js+formidable模块实现简单的文件上传

    /** * 原生node.js结合formidable模块实现图片上传改名 * @Author:Ghost * @Date:2016/07/15 * @description: * 1.引入模块htt ...

  4. Spring Boot + Vue 前后端分离,两种文件上传方式总结

    在Vue.js 中,如果网络请求使用 axios ,并且使用了 ElementUI 库,那么一般来说,文件上传有两种不同的实现方案: 通过 Ajax 实现文件上传 通过 ElementUI 里边的 U ...

  5. java常见3种文件上传速度对比和文件上传方法详细代码

    在java里面文件上传的方式很多,最简单的依然是FileInputStream.FileOutputStream了,在这里我列举3种常见的文件上传方法代码,并比较他们的上传速度(由于代码是在本地测试, ...

  6. 两种文件上传的实现-Ajax和form+iframe

    前言 话说现在很多很多项目需要用到文件上传,自从有了HTML5之后,上传就变的超级简单了.HTML5支持多图片上传,而且支持ajax上传,而且支持上传之前图片的预览,而且支持图片拖拽上传,而且还是纯粹 ...

  7. 基于tornado的文件上传demo

    这里,web框架是tornado的4.0版本,文件上传组件,是用的bootstrap-fileinput. 这个小demo,是给合作伙伴提供的,模拟APP上摄像头拍照,上传给后台服务进行图像识别用,识 ...

  8. WebSite 文件上传Demo

    知识点: 1 <!--上传文件时:        1.必须使用Post方式来提交数据        2.必须设置表单的enctype属性        3.必须在表单中包含文件域.input t ...

  9. java文件上传Demo

    说到文件上传我们要做到: 1.引入两个包:commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar 2.将form改为上传文件模式:enctype=" ...

随机推荐

  1. git操作+一个本地项目推到github上+注意

    git init 创建新文件夹,打开,然后执行以创建新的 git 仓库. git config --global user.name "xxx" git config --glob ...

  2. offic|集成|协同OA|移动办公|

    随着互联网时代的日新月异,移动通讯技术的飞速发展,移动网络技术的更新换代,手机.平板电脑等移动设备越来越智能化.越来越多样化,人们对移动办公的需求也在日益增长.在此背景下北京博信施科技有限公司自主研发 ...

  3. AEAI HR薪资汇总功能介绍

    1 概述 人力资源系统是一个公司重要的管理工具,而薪资管理是人力资源管理系统中最为核心的功能模块,它包括不同员工的薪资标准.薪资的组成部分,例如:对奖惩管理.保险和年假等员工必备的福利待遇进行统一管理 ...

  4. Truffle 4.0、Geth 1.7.2、TestRPC在私有链上搭建智能合约

    目录 目录 1.什么是 Truffle? 2.适合 Truffle 开发的客户端 3.Truffle的源代码地址 4.如何安装? 4.1.安装 Go-Ethereum 1.7.2 4.2.安装 Tru ...

  5. Spark读Hbase优化 --手动划分region提高并行数

    一. Hbase的region 我们先简单介绍下Hbase的架构和Hbase的region: 从物理集群的角度看,Hbase集群中,由一个Hmaster管理多个HRegionServer,其中每个HR ...

  6. SQL Server数据库————连接查询和分组查询

    SQL Server数据库————连接查询和分组查询 分组查询 select 列from  <表名> where  …… group by  列 注意:跟order  by一样group ...

  7. c/c++ 网络编程 UDP 发送端 bind 作用

    网络编程 UDP 发送端 bind 作用 upd 发送端 调用bind函数的效果:把socket特定到一个指定的端口,如果不调用bind,内核会随机分配一个端口. upd 发送端 调用bind函数的目 ...

  8. 【eclipse】mybatis配置文件创建与mapper接口文件创建

    什么是mybatis: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. mybatis配置文件: <?xml version="1.0" ...

  9. python文章装饰器理解12步

    1. 函数 在python中,函数通过def关键字.函数名和可选的参数列表定义.通过return关键字返回值.我们举例来说明如何定义和调用一个简单的函数: def foo(): return 1 fo ...

  10. 英语口语练习系列-C22-吃东西

    基础词汇 1. bill [bɪl] n. 账单:钞票:法案:鸟嘴 Bill (人名)比尔 pay the bill 付账单 telephone bill 话费单 electricity bill 电 ...