1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:sking
4 """
5 test_file.txt
6 文件内容如下:
7 打印字符串第一个字符
8
9 打印字符串第二个字符
10 """
11 #打开文件test_file.txt
12 f = open('test_file.txt', 'r+') #f是文件的文件句柄,它是在内存中的,是内存中的一个对象
13 data = f.read()
14 print(data)
15 """
16 data结果:
17 打印字符串第一个字符
18
19 打印字符串第二个字符
20 """
21 data2 = f.read() #再读一次文件
22 print("data2=", data2) #data2=
23 # 此时的结果是data2= ,也就是此时读取的data2为空,为什么?
24 # 因为第一次data读的时候文件光标是从头开始一直读到最后的,再次读的时候,
25 # 是从此时光标所在的位置(此时光标在最后面)开始读取,因为光标已经在最后了,
26 # 后面已经没有任何内容了,当然data2就读不出来数据了
27 # 可以用seek重新定位光标的位置
28 f.seek(0) #将光标定位到文件的开始位置
29 data3 = f.read()
30 print(data3)
31 """
32 data3结果:
33 打印字符串第一个字符
34
35 打印字符串第二个字符
36 """
37 #写文件write
38 #f = open('test_file.txt', 'w') #如果是'w'写的模式的时候,系统会自动创建一个这个名字的文件,
39 # 如果该目录下有这个名字的文件,系统会直接覆盖掉原来的文件,原来的文件及内容就不存在了,所以这点一定要注意。
40 #f.write('\n\n写入字符串第三个字符')
41 f.seek(0) #seekable()判断文件内容是否可以进行seek操作,因为有些文件是不可以进行seek的
42 data4 = f.read()
43 print(data4)
44 f.close()
45 """
46 打印字符串第一个字符
47
48 打印字符串第二个字符
49
50 写入字符串第三个字符
51 """
52 #向文件追加内容
53 f = open('test_file.txt', 'a') #'a'是append 追加,但是不能读取文件
54 f.write('\n\nhaha')
55 print(f.readable()) #False 判断文件是否可读
56 f.close()
57 #读取一行内容
58 f = open('test_file.txt', 'r')
59 data = f.readline()
60 print(data) # 打印字符串第一个字符
61 #读取多行
62 data2 = f.readlines()
63 print(data2)
64
65
66 #读取到第3行
67 for index, line in enumerate(f.readlines()): #仅适合读取小文件
68 print(line.strip())
69 if index == 2:
70 break;
71 f.close()
72 #读取大文件(推荐使用)
73 f = open('test_file.txt', 'r')
74 for line in f: #这样写的效果就是逐行读取文件中的内容,并且内存中始终仅保存读取的这一行内容 此时的f是一个迭代器
75 print(line)
76 f.close()
77 #查看文件游标所在的位置
78 f = open('test_file.txt', 'r')
79 print(f.tell()) #0
80 print(f.read(5))
81 print(f.tell()) #10 因为一个汉字占2个字节,所以这里显示的是10
82 f.close()
83 f2 = open('test_file2.txt', 'r')
84 print(f2.tell()) #0
85 print(f2.read(5))
86 print(f2.tell()) #5 因为一个英文占1个字节,所以这里显示的是5
87 f2.close()
88
89
90 f = open('test_file.txt', 'r+')
91 print(f.encoding) #cp936 #查看文件编码
92 print(f.name) # test_file.txt 查看文件名
93
94 #实时存储数据
95 #f.write("sdfadf") #因为代码执行的过程中并不是出现依据写到硬盘的代码就立马开始向硬盘存储。
96 #系统有一个阀门限制,系统会在内存中开辟一块用来临时存储的区域,当临时存储区域的数据达到一定值时,才会从内存存到硬盘上。
97 #所以并不是执行一行写的代码后,硬盘就一定已经保存了该结果,很可能该结果还没有被保存。
98 f.flush()
99 print(f.flush()) #None
100
101 f.close()
102
103 #截断字符truncate
104 f = open('test_file.txt', 'r+')
105 f.truncate(10) #打印字符串 从文件头开始截取10个字节(一个汉字是2个字节)
106 f.truncate() #如果什么都不写,就是截取0个字节也就相当于清空文件内容
107 f.close()
108
109 #写二进制文件内容
110 f = open('test_file.txt', 'wb')
111 f.write('hello'.encode(encoding='utf-8'))
112 f.close()
113
114 #演示进度条
115 import sys
116 import time
117 for i in range(31):
118 sys.stdout.write('#')
119 sys.stdout.flush()
120 time.sleep(0.3)
121
122
123 """
124 一、文件操作
125 1.文件处理的流程
126
127
128 1)打开文件,得到文件句柄并赋值给一个变量
129
130 2)通过句柄对文件进行操作
131
132 3)关闭文件
133
134 例如:
135
136 f = open('chenli.txt') #打开文件
137 first_line = f.readline()
138 print('first line:',first_line) #读一行
139 data = f.read()# 读取剩下的所有内容,文件大时不要用
140 print(data) #打印读取内容
141 f.close() #关闭文件
142
143
144 2.文件操作基本用法
145 1)基本用法:
146
147 file_object = open(file_name, access_mode = ‘r’, buffering = -1)
148
149 open函数有很多的参数,常用的是file_name,mode和encoding
150
151 file_name:打开的文件名,若非当前路径,需指出具体路径
152 access_mode文件打开模式
153 buffering的可取值有0,1,>1三个,0代表buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),>1表示初始化的buffer大小;
154 encoding表示的是返回的数据采用何种编码,一般采用utf8或者gbk;
155
156
157
158
159 2)文件打开模式
160
161 r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
162 w,只写模式【不可读;不存在则创建;存在则清空内容】
163 x, 只写模式【不可读;不存在则创建,存在则报错】
164 a, 追加模式【不可读文件,不存在则创建;存在则只追加内容】,文件指针自动移到文件尾。
165 "+" 表示可以同时读写某个文件
166
167 r+, 读写【可读,可写】
168 w+,写读【可读,可写】,消除文件内容,然后以读写方式打开文件。
169 x+ ,写读【可读,可写】
170 a+, 写读【可读,可写】,以读写方式打开文件,并把文件指针移到文件尾。
171 "b"表示以字节的方式操作,以二进制模式打开文件,而不是以文本模式。
172
173
174
175 rb 或 r+b
176 wb 或 w+b
177 xb 或 w+b
178 ab 或 a+b
179 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
180
181
182
183 3)以读r的方式打开文件
184
185
186
187 #!/usr/bin/env python
188 # -*- coding:utf-8 -*-
189 f=open('1.txt',encoding='utf-8',mode='r')
190 print(f)
191 data1=f.read()
192 print(data1)
193
194
195 1.txt
196
197 55542342
198 123
199 输出:
200
201 <_io.TextIOWrapper name='1.txt' mode='r' encoding='utf-8'>
202 55542342
203 123
204
205
206 补充:
207
208 复制代码
209 1)python中有三个方法来处理文件内容的读取:
210 read() #一次读取全部的文件内容。返回字符串
211
212 readline() #每次读取文件的一行。
213
214 readlines() #读取文件的所有行,返回一个字符串列表。
215
216 2)print(f.readable()) #判断文件是否是r模式打开的
217
218 3)print(f.closed) #判断文件是否是关闭状态
219
220 4)python中在文本文件内容移动的操作
221 file.seek(offset,whence=0) #从文件中给移动指针,从whence(0起始,1当前,2末尾)偏移offset个字节,正往结束方向移动,负往开始方向移动
222 file.tell() #返回当前文件中的位置。获得文件指针位置
223
224 5) file.truncate(size=file.tell()) #截取文件到最大size个字节,默认为当前文件位置
225 复制代码
226 4)以w方式写入文件
227
228 复制代码
229 f=open('a.txt','w',encoding='utf-8')
230 # f=open('b.txt','r',encoding='utf-8') #以读的方式打开文件,文件不存在则报错
231 f=open('b.txt','w',encoding='utf-8')
232 # print(f.writable())
233
234 f.write('111111\n22222222')
235 f.seek(0)
236 f.write('\n333333\n444444')
237
238 f.writelines(['\n55555\n','6666\n','77777\n'])
239 f.close()
240 复制代码
241 a.txt 为空
242
243 b.txt
244
245 333333
246 444444
247 55555
248 6666
249 77777
250
251
252 补充:
253
254 file.write(str) #向文件中写入字符串(文本或二进制)
255 file.writelines(seq) #写入多行,向文件中写入一个字符串列表,注意,要自己加入每行的换行符
256 file.flush() #刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入.
257
258
259 5)文件修改
260
261 复制代码
262 #!/usr/bin/env python
263 # -*- coding:utf-8 -*-
264 import os
265 read_f=open('b.txt','r')
266 write_f=open('.b.txt.swap','w')
267 for line in read_f.readlines():
268 if line.startswith('1111'):
269 line='2222222222\n'
270 write_f.write(line)
271 read_f.close()
272 write_f.close()
273 os.remove('b.txt')
274 os.rename('.b.txt.swap','b.txt')
275 复制代码
276
277
278 3.上下文管理with语句
279 当你做文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
280
281 正常情况下,代码如下:
282
283 file = open("/tmp/foo.txt")
284 data = file.read()
285 file.close()
286 这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。
287
288 然而with可以很好的处理上下文环境产生的异常。下面是with版本的代码:
289
290 with open("/tmp /foo.txt") as file:
291 data = file.read()
292 with的基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
293
294
295
296 补充:
297
298 模拟 tail -f access.log
299
300 复制代码
301 #!/usr/bin/env python
302 # -*- coding:utf-8 -*-
303
304 # tail -f access.log
305 import time
306 with open('access.log','r',encoding='utf-8') as f:
307 f.seek(0,2)
308 while True:
309 line=f.readline().strip()
310 if line:
311 print('新增一行日志',line)
312 time.sleep(0.5)
313 复制代码
314
315
316 """
317 """
318 read(),readline(),readlines()的区别
319
320 假设a.txt的内容如下所示:
321 123
322 Hello
323 Welcome
324 What is the fuck...
325
326 一、read([size])方法
327
328 read([size])方法从文件当前位置起读取size个字节,若无参数size,
329 则表示读取至文件结束为止,它范围为字符串对象
330 f = open("a.txt")
331 lines = f.read()
332 print(lines)
333 print(type(lines))
334 f.close()
335
336 输出结果:
337 Hello
338 Welcome
339 What is the fuck...
340 <type 'str'> #字符串类型
341
342 二、readline()方法
343
344 从字面意思可以看出,该方法每次读出一行内容,所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。
345
346 f = open("a.txt")
347 line = f.readline()
348 print(type(line))
349 while line:
350 print line,
351 line = f.readline()
352 f.close()
353
354 输出结果:
355
356 <type 'str'>
357 Hello
358 Welcome
359 What is the fuck...
360
361 三、readlines()方法读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。
362
363 f = open("a.txt")
364 lines = f.readlines()
365 print(type(lines))
366 for line in lines:
367 print (line)
368 f.close()
369
370 输出结果:
371 <type 'list'>
372 Hello
373 Welcome
374 What is the fuck...
375
376 四、linecache模块
377
378 当然,有特殊需求还可以用linecache模块,比如你要输出某个文件的第n行:
379
380 # 输出第2行
381 text = linecache.getline(‘a.txt',2)
382 print text,
383
384 对于大文件效率还可以。
385 """