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
"))
print(fn.write("222
"))
print(fn.write("333"))
fn.close()

 输出结果: 

可以自己定义换行符去写

fn=open("test1.txt","w")
print(fn.write("333
4444
555555"))
fn.close()

输出结果:

 writeline()

writelines() 方法用于向文件中写入一序列的字符串。

就是可以定义多个列表元素的方式去写,相当于一个for循环,取出第一个元素执行一下write,取出第二个元素执行一下write...

换行需要制定换行符

fn=open("test1.txt","w")
fn.writelines(['11111
','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
':
#         new_fn.write(old_line)
#     else:
#         new_line='hello av
'
#         new_fn.write(new_line)

# for old_line in old_fn:
#     if old_line == 'hello cangjingkong
':
#         new_fn.write('hello av
')
#         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
':
            new_fn.write('hello av
')
            continue 
        new_fn.write(old_line)



# os.remove('old')
os.rename('old','.old.swp')
os.rename('new','old')

  

原文地址:https://www.cnblogs.com/hui520/p/6407001.html