一、文件对象(文件操作符或者文件句柄)

文件对象不仅可以访问普通的磁盘文件,也可以访问任何其他类型抽象层面上的“文件。

一旦设置了合适的“钩子”,你就可以访问具有文件类型接口的其他对象,就好像访问的是普通文件一样。

内建函数open()返回一个文件对象,对该文件进行的后续操作都要用到它。还有大量的函数也会返回文件对象或是类文件(file-like)对象。

进行这种抽象处理的主要原因是许多的输入/输出数据结构更趋向于使用通用的接口。这样可以在程序行为和实现上保持一致。

请记住,文件只是连续的字节序列,数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成。

 

二、文件内建函数(open())

作为打开文件之门的“钥匙”,内建函数open()提供了初始化输入/输出(I/O)操作的通用接口。

open()内建函数成功打开一个文件后会返回一个文件对象,否则引发一个错误。

file_object = open(file_name,access_mode='r',buffering=-1 )

file_name:要打开的文件名字字符串,它可以是相对路径或者绝对路径。

access_mode:文件打开的模式。文件使用模式‘r’、‘w’或是‘a’模式来打开,分别代表读取、写入和追加。还有个“U”,代表通用换行符支持。

       ‘+’代表可读可写,‘b’代表二进制模式访问。

       对于linux系统来说,‘b’是可有可无的,因为它们把所有的文件当成二进制文件,包括文本文件。

buffering:指示访问文件所采用的缓冲方式。其中0表示不缓冲,1表示只缓冲一行数据。

     任何其他大于1的值代表使用给定给定值作为缓冲区,不提供该参数或者给定负值代表使用系统默认缓冲机制。

文件对象的访问模式

文件模式

操        作

r

以读方式打开,文件必须已经存在

rU或U

以读方式打开,同时提供通用换行符支持。

w

以写方式打开,如果文件存在则清空。

a

以追加模式打开,写入的数据追加到文件末尾

r+

以可读可写模式打开,如果先读后写,末尾追加;如果先写后读,首行覆盖,非常容易乱码

w+

以可写可读模式打开,尽管可读,文件直接被清空,如果想要读,那么要移动光标

a+

以读写模式打开

rb

以二进制读模式打开

wb

以二进制写模式打开

ab

以二进制追加模式打开

rb+

以二进制读写模式打开

wb+

以二进制读写模式打开

ab+

以二进制读写模式打开

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使用的较多的是:r、w、a、rb、wb、ab

当使用“U”标志打开文件的时候,所有的行分隔符都会被替换为分隔符。

open()打开文件依赖操作系统的提供的途径。

操作系统都有自己的编码,linux默认为utf-8,win默认gbk。所以跨系统时注意编码。

open()在打开文件的时候默认使用操作系统的编码。

路径前面加上r表示取消所有换行转义功能。

 

三、文件内建方法

open()成功执行并返回一个文件对象之后,所有对该文件的后续操作都将通过这个“句柄进行。

文件方法可以分为四类:输入、输出、文件内移动以及杂项操作。

 

1、输入

read():直接读取字符到字符串中,最多读取给定数目个字节。如果没有给定size参数(默认值为-1)或者size值为负,文件将被读取至末尾。

      r:按字符读,rb:按字节读

      缺点:占内存

f =open('123','r')
print(f.read())

abc   #一次打印所有内容
哈哈哈

 

readline():都去打开文件的一行,包括行结束符,作为字符串返回。

     和read()相同,也有一个可选参数,默认为-1,代表读至行结束符。如果提供了该参数,那么在超过size字节后不会返回完整的行。

     缺点:不知道到什么位置,文件结束

f =open('123','r')
print(f.readline())
print(f.readline())

abc     #一次打印一行

哈哈哈

 

readlines():读取所有(剩余)行然后把它们作为一个字符串列表返回。

f =open('123','r')
print(f.readlines())

['abc\n', '哈哈哈']

 

readable():判断文件是否可读

f =open('123','r')
print(f.readable())

True   #返回一个布尔值

 

注意:当使用输入方法如read()或readlines()从文件中读取行时,python并不会删除行结束符,这个操作留给了程序员。

   类似的,输出方法write()或者writelines()也不会自动加入行结束符,你应该向文件写入数据前自己完成。

还有两者方法也是类似的。

read(num):读取指定字符数

f =open('456','r')
print(f.read(5))

abcde

还有一种使用迭代来实现,使用的也是非常普遍。

f = open('练习')
for line in f:
    print(line)
f.close()

apple 10 3

tesla100000 1

mac 3000 2

lenovo 30000 3

 

 

2、输出

write():把含有文件数据或二进制数据块的字符串写入到文件中去。

writelines():接受一个字符串列表作为参数,将它们写入文件。

 writeable():判断文件是否可写

 

3、文件内移动

seek():可以在文件中移动文件指针到不同的位置,按照字节来计数。有三种模式,分别为0、1、2。0代表从头开始,2代表移动到末尾,2表示当前位置。

f = open('练习','r+')
# f.write('\nabcdefgh\n')
print(f.read())
print(f.tell())
print(f.read())   #这个read没有打印,因为指针
f.close()

结果:
 12345678
10

seek()一般不常用,因为容易造成乱码。

 

4、其他

close():关闭文件来结束对它的访问。python垃圾收集机制也会在文件对象的引用计数降至零时自动关闭文件。

    如果不显示的将文件关闭,那么你可能丢失输出缓冲区的数据。

fileno():返回打开文件的描述符。

flush():会直接把内部缓冲区中的数据立刻写入文件,而不是被动的等待输出缓冲区被写入。

isatty():是一个布尔内建函数,当文件是一个类tty设备时返回True,否则返回False。

trubcate():将文件截取到当前文件指针位置或者到给定size,以字节为单位。

     truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

12345678
abcdefgh        #原字符串

f = open('练习','a+')
f.truncate(10)
f.close()

 12345678   #为啥只有8个,win的换行符为\r\n,故而有两个字节

 

 del :主动释放了一个python程序内存中的变量。

5、文件方法杂项

先看两个例子:

filename = input('enter file name: ')
f = open(filename,'r')
allLines = f.readlines()
f.close()
for eachLine in allLines:
    print(eachLine)
上面这段代码读完所有的行才开始向屏幕输出,处理大文件时,有些不便。

filename = input('enter file name: ')
f = open(filename,'r')
for eachLine in f:
    print(eachLine)
f.close()
使用文件迭代器,每次只读取和显示一行

再看一个例子

import os
filename = input("Enter file name:" )
fobj = open(filename,'w',encoding='utf-8')
while True:
    aLine = input("Enter a line('.' to quit):")
    if aLine != ".":
        fobj.write('%s%s' % (aLine, os.linesep)),
    else:
        break
fobj.close()

 

还有一些需要注意:

操作系统间的差异之一是它们所支持的分隔符不同。Linux使用\n,而win支持\r\n。

print语句默认在输出内容末尾后加一个换行符,在语句后加一个逗号就可以避免。

readline()和readlines()函数不对行里的空白字符做任何处理,所以你必须加上逗号。

如果你省略逗号,那么显示出的文本每行后会有两个换行符。一个是默认添加,一个是print自动添加。

文件路径:如果文件路径和所处的路径相同,那么就可以直接使用绝对路径。

     如果文件路径和所处的路径不同,那么就必须使用绝对路径。

取消转义有两种方式:\\和r