python 文件基本操作
在python 3当中打开文件用open()这个函数,就是向操作系统发起一个系统调用的操作,就是告诉操作系统你给我打开一个文件
这里的“test.txt”就是文件路径、不加路径就代表相对路径
open("test.txt")
这个操作就相当于呼叫操作系统,操作系统会返回一个文件描述符,拿着这个文件描述符,就可以发起对硬盘的IO请求(读写请求)
什么叫文件描述符呢?有了它就相当于拿到了操作文件的一个工具
举个例子: 硬盘上的数据相当于一堆鱼的话,想要去取数据的过程就相当于取硬盘上捞鱼的过程,但是你现在捞不了,因为你没有工具,没有一个渔网,你得向操作系统要一个工具,也就是向操作系统发起一个请求,说:你得给我一个渔网,操作系统会针对你要打开的那个文件给你一个工具,这个工具就是渔网,拿着它,你就可以去硬盘上取数据 (捞鱼),这个捞鱼的过程是被操作系统控制的
一 文件的读操作:
read()
读取test.txt所有的内容
fn=open("test.txt") #打开test.txt data=fn.read() #读取test.txt文件的所有内容,赋值变量给data print(data) #打印data
输出结果:
readline()
readline()方法用于从文件读取整行,包括回车,(一次读一行)
fn=open("test.txt") print(fn.readline()) #读取文件的第一行 print(fn.readline()) #读取文件的第二行 print(fn.readline()) #读取文件的第三行
输出结果:
但是你会发现,那些空的一行是怎么来的呢?原来是print函数将你的回车也打印出来啦,想要去掉怎么办呢?可以用end来处理一下
fn=open("test.txt") print(fn.readline(),end="") #去掉末尾的回车,默认用空来代表 print(fn.readline(),end="") print(fn.readline(),end="")
是不是成功的去掉了呢?
readable()
判断文件可读不可读,文件有没有可读权限
fn=open("test.txt") print(fn.readable())
有就返回True,没有返回Flase
readlines()
readlines() 方法用于读取所有行并返回列表,每一行作为一个元素,包括回车(/n)
fn=open("test.txt") print(fn.readlines())
输出结果:
有的人会问,在结尾加上end能不能去掉回车呢?答案是不能的,因为这个是print的功能,而跟readlines没有关系,你不信?不信我给你看一下
fn=open("test.txt") print(fn.readlines(),end="")
输出结果:
看到了吧,并没有什么卵用,只是将列表下面的回车去掉了
循环文件
你灵机一动想出了一招:
fn=open("test.txt") for line in fn.readlines(): print(line)
隔壁老李看见了这几行代码,抱起你的儿子说道:可以可以,没毛病,但是这样做效率非常低,如果你的文件有10个G呢?虽然说服务器内存大,但咱也不能这么玩啊,万一你服务器上部署这其他应用咋办,太占内存了,弄不好容易宕机呀!
我听完以后,菊花一紧,后背吓出了一身冷汗,问隔壁老李:那咋整呢?,隔壁老李说:你看我给你写一段:
fn=open("test.txt") for line in fn: print(line)
直接循环fn就行,这是非常牛逼的一招,在python武学里叫做迭代器,你先记住可以以这种方式循环文件,日后我再详细传你,你听完以后你不禁心里感叹道:牛逼呀
隔壁老李又问道:如果我写两个循环来循环文件呢?会输出几遍?
fn=open("test.txt") for line in fn.readlines(): print(line) for line in fn: print(line)
你菊花一松,脱口而出:两遍,隔壁老李说心中暗叹道:我怎么放心把我儿子交给你这种人,隔壁老李说:我执行以一下你看下结果:
你再一旁惊呆了,卧槽,卧槽,卧槽嘞,为什么是一遍呢?难道不应该是两遍吗?
这时候隔壁老李摸了摸你儿子的头说道:你想啊,第一次readline是不是读文件将光标走到了末尾?不管是哪种循环,都是光标走到了文件末尾,第二次再循环一遍没有任何意义,所以就有一遍的效果,能明白不?
你默默的点了点头,仔细一瞅,儿子长得和隔壁老李有几分相似呢!
对了,还有非常重要的一点,不管什么文件操作,文件操作完毕以后一定要close,读写都要close
fn=open("test.txt") print(fn.readline(),end="") #去掉末尾的回车,默认用空来代表 print(fn.readline(),end="") print(fn.readline(),end="") fn.close() #关闭文件
这是为啥?因为你打开一个文件,操作系统会给你内存(会占内存),打一个占一个内存,不会释放,文件很大打开多了占内存。所以要关闭文件释放内存
其实还有一种方式来释放内存,和close一样的效果:
上下文管理
with open("test.txt") as fn: 用with的方式打开test.txt赋值给fn,等同于 fn=open("test.txt") print(fn.readlines())
写的时候一定要加冒号在下面写子代码块,这样写的好处就在于不用关闭文件,不用close,自动帮你close
读一个文件,这个文件必须存在,因为是基于存在的文件去读的,没有会报错
而写文件则会帮你创建出来.
二 写文件操作
其实刚才的open("test.txt")后面是可以加参数的,没有加是默认给你加了个“r”,那么写肯定就是“w”了
fn=open("test1.txt","w")
writable()
判断文件是否可写。可写返回True,否则返回Flase
fn=open("test1.txt","w") print(fn.writable())
fn.close()
write()
write() 方法用于向文件中写入指定字符串。
fn=open("test1.txt","w") print(fn.write("111"))
fn.close()
为什么会返回3呢?因为这是返回的你写了几个字符的值。你写了3个1,就返回了3
看一下文件:
真的写入了3个1
当然可以写入换行
fn=open("test1.txt","w") print(fn.write("111\n")) print(fn.write("222\n")) print(fn.write("333"))
fn.close()
输出结果:
可以自己定义换行符去写
fn=open("test1.txt","w") print(fn.write("333\n4444\n555555"))
fn.close()
输出结果:
writeline()
writelines() 方法用于向文件中写入一序列的字符串。
就是可以定义多个列表元素的方式去写,相当于一个for循环,取出第一个元素执行一下write,取出第二个元素执行一下write...
换行需要制定换行符 \n
fn=open("test1.txt","w") fn.writelines(['11111\n','aaaa','bbbbbb']) fn.close()
输出结果:
三 修改文件
import os # old_fn=open('old','r') # new_fn=open('new','w') # for old_line in old_fn: # if old_line != 'hello cangjingkong\n': # new_fn.write(old_line) # else: # new_line='hello av\n' # new_fn.write(new_line) # for old_line in old_fn: # if old_line == 'hello cangjingkong\n': # new_fn.write('hello av\n') # continue # new_fn.write(old_line) # # old_fn.close() # new_fn.close() #最终版本 with open('old','r') as old_fn,open('new','w') as new_fn: for old_line in old_fn: if old_line == 'hello cangjingkong\n': new_fn.write('hello av\n') continue new_fn.write(old_line) # os.remove('old') os.rename('old','.old.swp') os.rename('new','old')