Python -- 文件的copy以及读写


'''

打开文件并返回一个流。失败时提出错误。
文件是一个文本或字节字符串,给出名称(和路径
如果文件不在当前工作目录中),则
或要打开的文件的整数文件描述符
包裹。(如果给定了文件描述符,则当
返回的I/O对象是关闭的,除非closefd设置为False。)
mode是一个可选的字符串,它指定文件的模式
已打开。它默认为“r”,这意味着可以在文本中阅读
模式。其他常用值是“w”用于写入(如果
它已经存在),用于创建和写入新文件的“x”,以及
“a”表示附加(在某些Unix系统上,表示所有写入
追加到文件末尾,而不考虑当前的查找位置)。
在文本模式下,如果未指定编码,则使用的编码为平台
从属关系:locale.getpreferredencoding(False)调用以获取
当前区域设置编码。(对于读写原始字节,使用二进制
模式和未指定编码。)可用模式包括:
文字意义
--------- ---------------------------------------------------------------
“r”打开供读取(默认)

“w”打开进行写入,首先截断文件

“x”创建一个新文件并打开它进行写入

“a”打开进行写入,如果文件存在,则将其附加到文件末尾

“b”二进制模式

“t”文本模式(默认)

“+”打开磁盘文件进行更新(读写)

“U”通用换行模式(已弃用)
--------- ---------------------------------------------------------------
默认模式为“rt”(打开以阅读文本)。对于二进制随机
在b+0模式下打开文件,而b+w'则会截断文件
“r+b”打开文件而不截断。“x”模式意味着“w”和
如果文件已存在,则引发“FileExistsError”。
Python区分以二进制和文本模式打开的文件,
即使在底层操作系统没有的情况下
二进制模式(将“b”附加到模式参数)将内容返回
不进行任何解码的bytes对象。在文本模式下(默认,或
“t”附加到mode参数之后),文件的内容是
以字符串形式返回,首先使用
平台相关编码或使用指定的编码(如果给定)。



“U”模式已弃用,将在将来的版本中引发异常
巨蟒。它在python3中没有效果。使用换行符控制
通用换行模式。



缓冲是一个可选整数,用于设置缓冲策略。
传递0关闭缓冲(仅在二进制模式下允许),1选择
行缓冲(仅在文本模式下可用),整数>1表示
固定大小块缓冲区的大小。当没有缓冲参数时
给定,默认缓冲策略的工作方式如下:
*二进制文件以固定大小的块进行缓冲;缓冲区的大小
使用启发式方法来确定底层设备的
“块头大小”和倒下`io.DEFAULT U BUFFER U大小`.
在许多系统上,缓冲区通常为4096或8192字节长。



*“交互式”文本文件(isatty()返回True的文件)
使用线路缓冲。其他文本文件使用上述策略
对于二进制文件。



编码是用于解码或编码的编码的名称
文件。这只能在文本模式下使用。默认编码是
依赖于平台,但是Python支持的任何编码都可以
通过。有关支持的编码列表,请参阅编解码器模块。



errors是一个可选字符串,指定如何对错误进行编码
不应在二进制模式下使用此参数。通过
“strict”在存在编码错误时引发ValueError异常
(默认的“无”具有相同的效果),或传递“ignore”以忽略
错误。(请注意,忽略编码错误可能会导致数据丢失。)
请参阅文档编解码器.寄存器或者跑“救命”(编解码器。编解码器)'
允许的编码错误字符串的列表。



newline控制通用换行的工作方式(它只适用于文本
模式)。它可以是None、'\n'、'\r'和'\r\n'。它的工作原理是
跟随:
*输入时,如果newline为None,则通用newlines模式为
启用。输入中的行可以以'\n'、'\r'或'\r\n'结尾,并且
在返回到
来电者。如果为“”,则启用通用换行模式,但是
结尾未经翻译返回给调用者。如果它有
其他合法值、输入行仅由给定的
字符串,并且行尾返回给调用方未经翻译。



*在输出时,如果newline为None,则写入的任何'\n'字符都是
转换为系统默认行分隔符,操作系统linesep. 如果
换行符为“”或'\n',不进行转换。如果newline是
在其他合法值中,任何写入的'\n'字符都会被翻译
到给定的字符串。



如果closefd为False,则底层文件描述符将保持打开状态
当文件关闭时。当给定文件名时,这不起作用
在这种情况下一定是真的。



通过传递可调用的*opener*,可以使用自定义的开场白。这个
文件对象的底层文件描述符由
使用(*file*,*flags*)调用*opener*。*opener*必须返回一个open
文件描述符(传递操作系统打开as*开场白*带来功能性
类似于不及格)。



open()返回一个文件对象,其类型取决于模式,并且
通过它进行标准的文件操作,如读写
被执行。当open()用于以文本模式(“w”)打开文件时,
'r'、'wt'、'rt'等),它返回一个TextIOWrapper。用于打开时
在二进制模式下的文件,返回的类不同:在read binary中
模式,它返回一个BufferedReader;在write binary和append binary中
模式,它返回一个BufferedWriter,在读/写模式下,它返回
缓冲区。



也可以使用字符串或bytearray作为两者的文件
阅读和写作。对于字符串,StringIO可以像文件一样使用
以文本模式打开,对于字节,字节可以像文件一样使用
以二进制模式打开。
'''



f = open('E:\PyCharm_Demo\Dile_Arr\空姐.txt',mode='r',encoding='utf-8')
# content = f.read()
# content1 = f.readline().strip()
# content2 = f.readline()
# content3 = f.readline()
# content4 = f.readline()
# content5 = f.readline()
# content6 = f.readlines()
# print(content1)
# print(content2)
# print(content3)
# print(content4)
# print(content5)
# print(content6)
f.close()

'''
f: 就是一个变量,一般都会将它写成f,f_obj,file,f_handler,fh,等,它被称作文件句柄。

open:是Python调用的操作系统(windows,linux,等)的功能。

'd:\护士少妇萝莉.txt': 这个是文件的路径。

mode: 就是定义你的操作方式:r为读模式。

encoding: 不是具体的编码或者解码,
他就是声明:此次打开文件使用什么编码本。一般来说:你的文件用什么编码保存的,
就用什么方法打开,一般都是用utf-8(有些使用的是gbk)

f.read():你想操作文件,比如读文件,给文件写内容,等等,都必须通过文件句柄进行操作。

close(): 关闭文件句柄(可以把文件句柄理解成一个空间,这个空间存在内存中,必须要主动关闭)

readline()
readline()读取每次只读取一行,注意点:readline()读取出来的数据在后面都有一`个\n
readlines() 返回一个列表,列表里面每个元素是原文件的每一行,如果文件很大,占内存,容易崩盘

strip() 读取出来的文件不换行
read read(n) readline(),readlines() for
'''
# f = open('弟子规.txt',mode='r',encoding='utf-8')
# for line in f:
# print(line,end='')

# f = open('弟子规.txt',encoding='utf-8')
# print(f.readlines())
# f.close()


'''
r模式
以只读方式打开文件,文件的指针将会放在文件的开头。是文件操作最常用的模式,也是默认模式,
如果一个文件不设置mode,那么默认使用r模式操作文件
rb模式:
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。记住下面讲的也是一样,
带b的都是以二进制的格式操作文件,他们主要是操作非文字文件:图片,音频,视频等,并且如果你要是带有b的模式操作文件,
那么不用声明编码方式。
当然rb模式也有read read(n) readline(),readlines() for循环这几种方法,我在这就不一一演示了
w模式
如果文件不存在,利用w模式操作文件,那么它会先创建文件,然后写入内容.
如果文件存在,利用w模式操作文件,先清空原文件内容,在写入新内容。
wb模式
wb模式:以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,
并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如:图片,音频,视频等。
举例说明:
我先以rb的模式将一个图片的内容以bytes类型全部读取出来,然后在以wb将全部读取出来的数据写入一个新文件,
这样我就完成了类似于一个图片复制的流程。具体代码如下:
把‘美女.jpg’读了再写进来


open 打开
close 关闭
read 读
write 写
tell 告诉
seek 探寻
flush 冲刷
encoding 编码格式

'''
f = open('E:\PyCharm_Demo\Pachong_Module\卡片原画\三教九流.jpg',mode='rb') #打开要读的图片路径
fw = open('三教九流1.jpg',mode='wb') #要写入的图片路径
fw.write(f.read()) #读取并写入图片
fw.close() #关闭流`
f.close()


'''
文件的追加
第三类就是追加,就是在文件中追加内容。这里也有四种文件分类主要四种模式:a,ab,a+,a+b
a模式
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。
如果该文件不存在,创建新文件进行写入。
   如果文件不存在,利用a模式操作文件,那么它会先创建文件,然后写入内容。
如果文件存在,利用a模式操作文件,那么它会在文件的最后面追加内容

件操作的其他模式
什么是带+的模式呢?+就是加一个功能。比如刚才讲的r模式是只读模式,在这种模式下,
文件句柄只能进行类似于read的这读的操作,而不能进行write这种写的操作。所以我们想让这个文件句柄既可以进行读的操作,
又可以进行写的操作,那么这个如何做呢?这就是接下来要说这样的模式:r+ 读写模式,w+写读模式,a+写读模式,r+b 以bytes类型的读写模式.........
在这里咱们只讲一种就是r+,其他的大同小异,自己可以练练就行了

模式
1. 打开文件的模式有(默认为文本模式):
r, 只读模式【默认模式,文件必须存在,不存在则抛出异常】
w, 只写模式【不可读;不存在则创建;存在则清空内容】
a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】
t 文本模式 (默认)。
x 写模式,新建一个文件,如果该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(不推荐)。
2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

3,‘+’模式(就是增加了一个功能)
r+, 读写【可读,可写】打开一个文件用于读写。文件指针默认将会放在文件的开头 注意:如果你在读写模式下,先写后读,
那么文件就会出问题,因为默认光标是在文件的最开始,你要是先写,则写入的内容会讲原内容覆盖掉,直到覆盖到你写完的内容,
然后在后面开始读取
w+,写读【可写,可读】
a+,写读【可写,可读】

4,以bytes类型操作的读写,写读,写读模式
r+b,读写【可读,可写】
w+b,写读【可写,可读】
a+b,写读【可写,可读】

文件操作的其他功能
1 read(n)
    1. 文件打开方式为文本模式时,代表读取n个字符
    2. 文件打开方式为b模式时,代表读取n个字节
2 seek()
seek(n)光标移动到n位置,注意: 移动单位是byte,所有如果是utf-8的中文部分要是3的倍数
通常我们使用seek都是移动到开头或者结尾
移动到开头:seek(0)
移动到结尾:seek(0,2) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾


方法
file.closed 返回true如果文件已被关闭,否则返回false。
file.mode 返回被打开文件的访问模式。
file.name 返回文件的名称。
file.softspace 如果用print输出后,必须跟一个空格符,则返回false。否则返回true。
rename()方法需要两个参数,当前的文件名和新文件名。 os.rename(文件名, 新文件名)
remove()方法删除文件,需要提供要删除的文件名作为参数。
mkdir()方法可以使用os模块的mkdir()方法在当前目录下创建新的目录们。你需要提供一个包含了要创建的目录名称的参数。
chdir()方法可以用chdir()方法来改变当前的目录。chdir()方法需要的一个参数是你想设成当前目录的目录名称。
getcwd()方法:getcwd()方法显示当前的工作目录。
rmdir()方法rmdir()方法删除目录,目录名称以参数传递。在删除这个目录之前,它的所有内容应该先被清除。
'''



# f = open('E:\PyCharm_Demo\Dile_Arr\空姐.txt',mode='r+',encoding='utf-8')
# se = f.read(5) #读取5个字符
# print(se)
# t = f.tell() #查询指针所在位置
# print('光标所在:',t)
# f.seek(0,2) #光标移动到结尾
# f.write('opq')
# se = f.read()
# print(se,'----')


'''
打开文件的另一种方式
这里要注意一个问题,虽然使用with语句方式打开文件,不用你手动关闭文件句柄,
比较省事儿,但是依靠其自动关闭文件句柄,是有一段时间的,这个时间不固定,
所以这里就会产生问题,如果你在with语句中通过r模式打开t1文件,那么你在下面又以a模式打开t1文件,
此时有可能你第二次打开t1文件时,第一次的文件句柄还没有关闭掉,可能就会出现错误,
他的解决方式只能在你第二次打开此文件前,手动关闭上一个文件句柄。
'''

# 1,利用with上下文管理这种方式,它会自动关闭文件句柄。
# with open('弟子规.txt', encoding='utf-8',mode='r+') as f1:
# f1.read()
# f1.write('弱智')

# 2,一个with 语句可以操作多个文件,产生多个文件句柄。
# with open('t1', encoding='utf-8') as f1, \
# open('Test', encoding='utf-8', mode='w') as f2:
# f1.read()
# f2.write('小美女你好呀')


'''
文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,
我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,
修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

'''
import os # 调用系统模块
with open('空姐.txt') as read_f,open('aaaaa.txt','w') as write_f:
data=read_f.read() #全部读入内存,如果文件很大,会很卡
data=data.replace('alex','SB') #在内存中完成修改

write_f.write(data) #一次性写入新文件


'''
1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。

apple 10 3

tesla 100000 1

mac 3000 2

lenovo 30000 3

chicken 10 3

通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。

'''

# l = []
# l3 = []
# with open('a.txt',mode='r',encoding='utf-8') as f1:
# for i in f1:
# l.append(i.strip().split())
# print(l)
# for i in range(len(l)):
# dic = dict(zip(['name','price','amount'],l[i]))
# l3.append(dic)
# print(l3)
# num = 0
# for i in l3:
# num += int(i.get('price')) * int(i.get('amount'))
# print('总价钱是:',num)

# for i in range(1,10+1):
# print(
# ' '*(10-i)+'那好吧'*(2*i-1)
# )



# l3 = []
# l = []
# with open('a.txt',mode='r',encoding='UTF8') as f :
#
# for i in f:
# se = i.strip().split(' ')
# dic = {'name':se[0],'price':se[1],'amount':se[2]}
# l.append(dic)
# num = 0
# for i in l:
# num += int(i.get('price')) * int(i.get('amount'))
#
# print(num)

# dic = dict(('name','a'))
# Unexpected type(s): (Tuple[str, str]) #字符串是不可迭代的,没办法形成映射关系,元组是不可迭代对象
# Possible types: (Mapping) (Iterable[Tuple[Any, Any]]#加上[]就变成了list,list是可迭代对象,就有了映射关系,
posted @ 2020-07-21 10:48  Ric_A  阅读(484)  评论(0编辑  收藏  举报