首页 > 第三章| 3.1文件处理

第三章| 3.1文件处理

1、三元运算

简单条件语句:

if 条件成立:val = 1
else: val = 2 

改成三元运算:

val = 1 if 条件成立 else 2

2、文件处理 (用python对硬盘上的文件操作)

读取文件的三个方法:read()、readline()、readlines()

三个方法均可接受一个变量用以限制每次读取的数据量,通常不使用该变量。

关于read()方法: 1、读取整个文件,将文件内容放到一个字符串变量中 2、如果文件大于可用内存,不可能使用这种处理

关于readline()方法: 1、readline()每次读取一行,比readlines()慢得多 2、readline()返回的是一个字符串对象,保存当前行的内容

关于readlines()方法: 1、一次性读取整个文件。 2、自动将文件内容分析成一个行的列表。

 

f = open(file = "兼职白领学生空姐模特护士联系方式.txt",mode="r",encoding="utf-8") #r模式以什么方式存的就要以什么方式读出来。如果文件是gbk格式,就encoding=“gbk”
data = f.read() #read方法是把文件全部读出到屏幕输出;readline是读取文件的一行信息;readlines是读取整个文件,输出屏幕的是一行包含所有的信息。
print(data)  
f.close() #一定要加上这个,不然数据文件数据就没有了,哎呀
read打印:
王心       北京    159    46    13813234424
马纤羽     深圳    173    50    13744234523
乔亦菲     广州    172    52    15823423525
罗梦竹     北京    175    49    18623423421
刘诺涵     北京    170    48    18623423765
岳妮妮     深圳    177    54    18835324553
贺婉萱     深圳    174    52    18933434452
叶梓萱     上海    171    49    18042432324
杜姗姗     北京    167    49    13324523342
black girl 河北    167    50    135423422334readline:
王心       北京    159    46    13813234424readlines:
['王心       北京    159    46    13813234424
', '马纤羽     深圳    173    50    13744234523
', '乔亦菲     广州    172    52    15823423525
', '罗梦竹     北京    175    49    18623423421
', '刘诺涵     北京    170    48    18623423765
', '岳妮妮     深圳    177    54    18835324553
', '贺婉萱     深圳    174    52    18933434452
', '叶梓萱     上海    171    49    18042432324
', '杜姗姗     北京    167    49    13324523342
', 'black girl 河北    167    50    135423422334']


存在硬盘上是二进制。以什么方式存的文件,就要以什么样的方式打开这个文件。此处的encoding必须和文件在保存时设置的编码一致,不然“断句”会不准确从而造成乱码。

r文本模式
二进制转换为字符串。open把它转一下。


rb为二进制模式,把这段内容直接读到内存里边来,硬盘怎么存的就怎么拿来,不用它转了。 视频、图片或者网络传输的文本,都是二进制模式。

f = open(file = "兼职白领学生空姐模特护士联系方式.txt",mode="rb") #二进制模式就不需要encoding了
data = f.read()
print(data)  #打印出来就是二进制格式
f.close()
打印:
b'xe7x8ex8bxe5xbfx83       xe5x8cx97xe4xbaxac    159    46    13813234424
xe9xa9xacxe7xbaxa4xe7xbexbd     xe6xb7xb1xe5x9cxb3    173    50    13744234523
xe4xb9x94xe4xbaxa6xe8x8fxb2     xe5xb9xbfxe5xb7x9e    172    52    15823423525
xe7xbdx97xe6xa2xa6xe7xabxb9     xe5x8cx97xe4xbaxac    175    49    18623423421
xe5x88x98xe8xafxbaxe6xb6xb5     xe5x8cx97xe4xbaxac    170    48    18623423765
xe5xb2xb3xe5xa6xaexe5xa6xae     xe6xb7xb1xe5x9cxb3    177    54    18835324553
xe8xb4xbaxe5xa9x89xe8x90xb1     xe6xb7xb1xe5x9cxb3    174    52    18933434452
xe5x8fxb6xe6xa2x93xe8x90xb1     xe4xb8x8axe6xb5xb7    171    49    18042432324
xe6x9dx9cxe5xa7x97xe5xa7x97     xe5x8cx97xe4xbaxac    167    49    13324523342
black girl xe6xb2xb3xe5x8cx97    167    50    135423422334'

 

自动检测编码:(不知道原文件是什么编码)
import chardet
f = open('log',mode='rb')
data = f.read()
f.close()result = chardet.detect(open('log',mode = 'rb').read())
print(result)  #{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

 

 循环文件 (边读边处理,内存就存一小块。)

f = open("兼职白领学生空姐模特护士联系方式.txt",'r',encoding="gbk")
for line in f:print(line)
f.close()
#循环打印出:

王心 北京 159 46 13813234424马纤羽 深圳 173 50 13744234523乔亦菲 广州 172 52 15823423525罗梦竹 北京 175 49 18623423421刘诺涵 北京 170 48 18623423765岳妮妮 深圳 177 54 18835324553贺婉萱 深圳 174 52 18933434452叶梓萱 上海 171 49 18042432324杜姗姗 北京 167 49 13324523342black girl 河北 167 50 135423422334

 

写文件(w是创建不是修改,没有就清空覆盖了。)   w给转换,而wb 二进制的就不用转换了。

f = open("兼职.txt",'w',encoding = "gbk") #创建一个文件以gbk的形式
f.write(“路飞学城!”) #”路飞学城”是以unicode的形式写的,再编码为gbk
f.close()
f = open("兼职2.txt",'wb') #创建一个兼职2的文件
f.write(“路飞学城!”.encode("gbk")) #encode下表示以什么样的编码存在
f.close()
f = open("兼职.txt",'wb')
f.write("原子二号".encode("gbk")) #新写进去的没有的就清除再创建,会把原来的文件被清空了。
f.close()

 

追加模式(修改,追加到文件尾部。以a或者ab的模式打开)

f = open("兼职白领学生空姐模特护士联系方式.txt",'ab') #以ab的模式打开 
f.write("
肛娘    北京  167   55   13312340322”.encode("gbk"))#追加到文件后面,
为换行
f.close()

比如:追加“给岁月以文明,而不是给文明以岁月”在第五行。(就是把其他的内容往下挤,不是覆盖第五行)(见练习题)

lines = []
f = open('三体语录','r',encoding='utf-8')
for line in f:lines.append(line)
lines.insert(5,'给岁月以文明,而不是给文明以岁月
')
s = ''.join(lines)  #把列表转成字符串
with open('三体语录','w',encoding='utf-8')as f_write:f_write.write(s)f_write.close()

 

混合操作(既能写又能读即 读写模式。r+ )

   

  读写就相当于append,只是多了个可以读。

写读模式 w+  (几乎没什么应用场景)

读写是先读后写,以读的模式打开然后往后继续追加;写读模式,是以写的模式打开(就是创建的模式)支持你读,把你写的读出来,但是之前的被清空了。

  

文件操作的其他功能

   def fileno(self, *args, **kwargs): # real signature unknown返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到def flush(self, *args, **kwargs): # real signature unknown把文件从内存buffer里强制刷新到硬盘def readable(self, *args, **kwargs): # real signature unknown判断是否可读def readline(self, *args, **kwargs): # real signature unknown只读一行,遇到
 or 
为止def seek(self, *args, **kwargs): # real signature unknown把操作文件的光标移到指定位置*注意seek的长度是按字节算的, 字符编码存每个字符所占的字节长度不一样。如“路飞学城” 用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(4) 就把光标切换到了“飞”和“学”两个字中间。但如果是utf8,seek(4)会导致,拿到了飞这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf8处理不了了,因为编码对不上了。少了一个字节def seekable(self, *args, **kwargs): # real signature unknown判断文件是否可进行seek操作def tell(self, *args, **kwargs): # real signature unknown返回当前文件操作光标位置 def truncate(self, *args, **kwargs): # real signature unknown按指定长度截断文件*指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。def writable(self, *args, **kwargs): # real signature unknown判断文件是否可写

 

flush 强制把内存刷到硬盘。

  flush() 方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入,   正常情况下缓冲区满时,操作系统会自动将缓冲数据写入到文件中。

一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。

   至于close方法,原理是内部先调用flush方法来刷新缓冲区,再执行关闭操作,这样即使缓冲区数据未满也能保证数据的完整性。

   

readline()

 tell()返回当前文件操作光标位置;  seek()把操作文件的光标移到指定位置。

    

seek(3)真的是字符吗?不是的,seek是找的是字节。  tell()是寻找光标的位置 。read是读的字符,tell和seek是找的字节。

utf-8中一个中文占3个字节,gbk中一个中文占2个字节。

>>>f = open('兼职白领学生空姐模特护士联系方式.tex',‘r’, encoding='gbk')   #文件里边:hello world! 
>>>f.seek(3)
3
>>>f.readline()
'lo world!'

  

 

 truncate()按指定长度截断文件 要以r+的模式打开   *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。

 

    

 文件修改 (两种方式:要么占内存要么占硬盘)

 把光标seek到中间的位置就可以了。

占硬盘修改,打开旧文件一行行的读,新文件一行行的写。  最后把新文件重命名为旧文件,就把它覆盖掉了。命名要 import os

import os

f_name = "兼职白领学生空姐模特护士联系方式.txt" f_new_name = "%s.new" %f_nameold_str = "乔一菲" new_str = "红娘"f = open(f_name,"r",encoding="utf-8") f_new = open(f_new_name,"w",encoding="utf-8")for line in f:if old_str in line:line = line.replace(old_str,new_str)f_new.write(line)f.close() f_new.close()os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了
 

占内存方式:以r+模式打开文件全read在内存,直接.replace,全程读一遍然后再seek到文件开头,再写进去就覆盖掉了。不一定能全部覆盖,怎么办:先把文件truncate完,flush

#占内存方式修改 
f = open('兼职白领学生空姐模特护士联系方式.txt','r+',encoding='utf-8')
f1 = f.readlines()
f.seek(0)  #这个一定要加
old_str = "乔亦菲"
new_str = "Yifei Qiao"
for line in f1:if old_str in line:line = line.replace(old_str,new_str)f.write(line)
#f.truncate()
#f.flush()
f.close()
#################
f = open(r"info.txt", "r+")
l = f.readlines()
f.seek(0)  # 指针指向文件开头
old_str = "唐三"
new_str = ""
for line in l[0::2]:  # 只取部分字符if old_str in line:line = line.replace(old_str,new_str)f.write(line+"
")
f.truncate()
# 对文件进行截取,如果文件之前为100M,
# 修改后文件只覆盖了50M,如果不使用truncate不会整体覆盖,只会部分覆盖,后面剩余的50M内容会追加新文件中,修改后的文件大小不变
# 使用truncate后,文件就只有50M,他会把剩余的50M内容从当前write的指针后面进行截取
f.close()

 对文件的删除

如:删除最后一行

with open('三体语录','r',encoding='utf-8') as f:f1 = f.readlines()  ##readline 和readlines的区别with open('三体语录','w',encoding='utf-8')as f_w:for line in f1:if '25' in line:continue  #跳出本次循环f_w.write(line)

 

转载于:https://www.cnblogs.com/shengyang17/p/8570312.html

更多相关:

  • 本文来自 运维人生 ,作者:fly是个稻草人链接:http://www.ywadmin.com/?id=76误删除linux系统文件了?不用急,本文将给你一个恢复linux文件的方法,让你轻松应对运维中的各风险问题。方法总比问题多~说在前面的话针对日常维护操作,难免会出现文件误删除的操作。大家熟知linux文件系统不同win有回收...

  • 原文来自SecIN社区—作者:WiHat0x00 什么是WebShell渗透测试工作的一个阶段性目标就是获取目标服务器的操作控制权限,于是WebShell便应运而生。Webshell中的WEB就是web服务,shell就是管理攻击者与操作系统之间的交互。Webshell被称为攻击者通过Web服务器端口对Web服务器有一定的操作权限,而...

  • 断电时文件系统发生了什么?硬盘又发生了什么?下一次开机时写到一半的文件在系统层面还在吗?在底层还在吗?更进一步的, 文件系统如何保证事务性, 会不会存在某种极端情况导致例如最后几个bit还没写完, 文件系统却认为它成功了的情况?回答不限任何文件系统,谢谢!下面是「北极」的回复分享断电的一瞬间,很多事情是无法确定的:1. 你无法确定...

  • 接到项目需求。需要搭建一个页面进行交互,慢慢来b (2).jpg使用python django框架进行页面的搭建在项目文件下打开窗口,输入命令;django-admin startproject helloword#在文件helloword/helloword/创建view.py在view.py文件中输入以代码from django....

  • 常见的错误集合解决方案(一)No.1提示错误'Microsoft.VC90.CRT,version="9.0.21022.8"把Microsoft.NET Framework 3.5.1下面的全部勾选上。No.2解决Qt Designer设计的图标但是VS生成不显示问题描述:在Qt designer中为菜单栏和工具栏设计的图标,但是...

  • 首先说明:虽然是原创,但有部分内容是借鉴了这位兄弟的文章:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27673206&id=3772566 按照这篇文档,你可以部署成功,但其中一些细节没有描述清楚。或者有后遗症,导致你的*** client无法ping通内网。好了...

  • 一,开始安装过程:1,三个包open***-2.1-0.29.rc15.el5.i386.rpmlzo-2.02-2.el5.1.i386.rpm           lzo-devel-2.02-2.el5.1.i386.rpm 2,查看一下文件分布:[root@xxw src]# find / -name open***/etc...