对文件的操作--

此文为转来的,原文地址为:http://www.cnblogs.com/BeginMan/p/3166644.html 和 http://www.cnblogs.com/BeginMan/p/3169020.html

 

一、文件对象

我理解的文件对象就是一个接口,通过这个接口对文件进行相关操作。

《Python 核心编程》上说的很晦涩,这里没有深刻理解到,希望有人能解释给我听。

复制代码
>>> f = open('demo.txt','r')
>>> f
<open file 'demo.txt', mode 'r' at 0x00CCCEC0>
>>> type(f)
<type 'file'>
复制代码

二、相关函数

[1]、内建函数:open()

提供了初始化输入/输出(I/O)操作的通用接口,成功打开一个文件后会返回一个文件对象,否则发生IOError异常。语法如下:

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

分析如下:

1):file_name:表示要打开文件名字的字符串,可以是相对路径也可以是绝对路径。
如:我在D盘新建一个空白名为out的文本文件,然后进行相关操作。

>>> f = open('../out.txt','w')
>>> f.write('good')
>>> f.close()

则打开该文件后,发现'good'已经写入进去了。

接下来使用绝对路径进行访问,如下:

>>> f = open('D:/out.txt','r')
>>> f.read()
'good'
>>> f.close()

2、可选变量access_mode也是字符串,代表文件打开模式。

注意:

1):使用'r'或'U'模式打开的文件必须已经存在

2):'w'模式打开的文件若存在则先清空,然后重新创建

3):'a'模式打开的文件是为了追加数据做准备的,所有写入的数据将追加到文件末尾。如果文件不存在,则自动被创建。

4):'+'代表可读可写

5):'b'代表二进制模式访问

6):默认情况下是 'r'

3、buffering可选参数,用于指示访问文件所采用的缓存方式。0表示不缓存;1表示只缓存一行,n代表缓存n行。如果不提供或为负数,则代表使用系统默认的缓存机制。

关闭文件:

打开文件消耗系统资源, 并且依赖于文件模式, 其它程序或许不能访问它们。这就是一旦操作完毕就该关闭文件的重要所在。

接上面的操作,加入还没有关闭:

复制代码
>>> f.closed  #判断是否关闭
False
>>> f.close() #关闭方法
>>> f.closed
True
>>> f.tell()  #如果已关闭,则一切针对文件操作都无效

Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    f.tell()
ValueError: I/O operation on closed file
>>> 
复制代码

 

[2]、工厂函数file()

与open()一样,可相互替换

>>> f = file('../out.txt','r')
>>> f.read()
'good'
>>> f.close()

三、相关方法

返回一个文件对象后(句柄),其实我也不清楚到底什么是句柄,这里摘自百度百科:

句柄,是整个windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一 个四字节长的数值,来标志应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。 句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来标志很多对象。

一般与文件相关的方法无非是:输入、输出、文件内移动、杂项

[1]、输入

1、read():读取字节到字符串中,有可选参数size,默认是-1,如果为-1或复数则文件将会被读取到文件末尾。

>>> f.read()
'good'
>>> f.read(2)
'go'

2、readline():读取文件的一行,包括行结束符。同read()也有个可选参数size。

3、readlines():读取所有(剩余的)然后将它们作为字符串列表返回,它有个可选参数sizhint代表返回的最大字大小。

>>> f = file('../out.txt','r')
>>> f.readlines()
['good']

 [2]、输出

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

2、writelines():针对列表操作,接受一个字符串列表作为参数,将它们写入文件,行结束符并不会被自动加入,如果需要的话必须在调用writelines方法前给每一行结尾加上结束符。

复制代码
>>> f =  open('d:/out.txt','w')
>>> f.writelines(['man'])
>>> f.close()
>>> f =  open('d:/out.txt','r')
>>> f.read()
'man'
复制代码

【注意:】

当使用read()或者readlines()从文件中读取行时,Python并不会删除行结束符,这个操作留给了程序员。

复制代码
>>> f.readlines()
['game is your life,game is your life,game is your life,game is your life,game is your life,[*]\n', 'game is your life,game is your life,game is your life[]']

---------------------------
>>> f = open('demo.txt','r')
>>> data = [line.strip() for line in f.readlines()]
>>> data
['game is your life,game is your life,game is your life,game is your life,game is your life,[*]', 'game is your life,game is your life,game is your life[]']
复制代码

类似的,write()和writelines()也不会自动加入行结束符,应该自己添加。

>>> f = open('demo.txt','w')
>>> f.writelines([' my name is BeginMan\n,I like coding'])
>>> f.close()

打开该文件可查看:

 [3]、文件内移动

tell()、seek()方法

复制代码
f = open('d:/out.txt','rb')
print f.tell()  #[1]
f.seek(10,1)    #[2]
print f.tell()  #10
print f.read(10)    # BeginMan,
print f.read(18)    #I like coding.
print f.tell()  #38

"""
【1】:tell():
tell 方法确认了已经移到当前文件位置
一个文件对象维护它所打开文件的状态。文件对象的 tell 方法告诉你在打开文件中的当前位置。
因为我们还没有对这个文件做任何事,当前位置为 0,它是文件的开始处。
"""
"""
【2】:seek():
文件对象的 seek 方法在打开文件中移动到另一个位置。第二个参数指出第一个参数是什么意思:
0 表示移动到一个绝对位置 (从文件开始算起),
1 表示移到一个相对位置 (从当前位置算起),
还有 2 表示文件末尾
"""
复制代码

[4]、文件迭代

复制代码
>>> f = open('d:/out.txt','rb')
>>> for eachline in f:
    eachline

    
'my name is BeginMan,\r\n'
'I like coding.\r\n'
复制代码

 四、相关属性

file.closed:文件已被关闭,否则为False

file.mode:文件访问模式

file.name:文件名称

>>> f.mode
'r'
>>> f.name
'demo.txt'

 五、文件系统

从系统角度来看,文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。

Python对文件系统的操作是通过os模块实现。提供了访问操作系统功能的接口,但是这个os模块只是一个伪文件系统操作,真正的“模块”如,dos,os2等,这些是直接的底层工作,而Python的os模块只是一种借用操作(个人理解)

os.path模块可对路径进行相关操作。

os、os.path这两个模块与平台、操作系统无关。

 六、os模块的文件/目录访问函数

函数描述
文件处理  
mkfifo()/mknod() 创建命名管道/创建文件系统节点
remove(path)/unlink(path) 删除文件 如:os.remove('d:\\b.png')
rename(old, new)/renames(old, new)  重命名文件:如:os.rename('d:\\b.png','d:\\a.png')
stat(path)  返回文件信息:
>>> os.stat('d:\\a.png')
(33206, 0L, 0, 0, 0, 0, 4088L, 1372746141, 1372734171, 1372746141)
>>> 
symlink()  创建符号链接
utime()    更新时间戳
tmpfile()  创建并打开('w+b')一个新的临时文件,注意不含参数,一旦执行则创建一个临时文件,类型未知
>>> os.tmpfile()#创建临时文件
<open file '<tmpfile>', mode 'w+b' at 0x011D4BF0>
>>> os.rename('d:\\t58g.2','d:\\abc.txt')#改成txt
walk(top, topdown, onerror)  生成一个目录树下所有文件名
目录/文件夹  
chdir(path)  改变当前工作目录
listdir(path)  列出指定目录文件
>>> os.listdir('d:\\')
['a.png', 'abc.txt', 'out.txt', 'Program Files', 'Python25', 'RECYCLER',]>>> 
getcwd()/getcwdu()  返回当前目录:
>>> os.getcwd()
'D:\\Python25'
>>> os.getcwdu()
u'D:\\Python25
mkdir(path)/makedirs(name, mode) 创建目录/创建多层目录
>>> os.mkdir('D:\\file')

rmdir(path)/removedirs(name)  删除目录/删除多层目录
访问/权限  
access(path, mode)  验证权限目录
chmod(path, mode)  更改权限模式
文件描述符操作  
open()、read()、write()  见上一节
dup()/dup2()  复制

 

对上面问题的几点解释:

1、os.walk()和os.path.walk()

os.walk()
函数声明:walk(top,topdown=True,onerror=None)
1>参数top表示需要遍历的目录树的路径
2>参数topdown的默认值是"True",表示首先返回目录树下的文件,然后在遍历目录树的子目录.Topdown的值为"False"时,则表示先遍历目录树的子目录,返回子目录下的文件,最后返回根目录下的文件
3>参数onerror的默认值是"None",表示忽略文件遍历时产生的错误.如果不为空,则提供一个自定义函数提示错误信息后继续遍历或抛出异常中止遍历
4>该函数返回一个元组,该元组有3个元素,这3个元素分别表示每次遍历的路径名,目录列表和文件列表
os,walk()实例:
import os
def VisitDir(path):
  for root,dirs,files in os.walk(path):
    for filespath in files:
      print os.path.join(root,filespath)
if __name__=="__main__":
path="/root"
VisitDir(path)

#如果能有人把这一段代码的作用是什么解释一下就好了
  
os.path.walk()
函数声明:walk(top,func,arg)
1>参数top表示需要遍历的目录树的路径
2>参数func表示回调函数,对遍历路径进行处理.所谓回调函数,是作为某个函数的参数使用,当某个时间触发时,程序将调用定义好的回调函数处理 某个任务.回调函数必须提供3个参数:第1个参数为walk()的参数tag,第2个参数表示目录列表,第3个参数表示文件列表
3>参数arg是传递给回调参数func的元组.回调函数的一个参数必须是arg,为回调函数提供处理参数.参数arg可以为空
os.path.walk()实例:
import os,os.path
def VisitDir(arg,dirname,names):
  for filespath in name:
    print os.path.join(dirname,filespath)
if __name__=="__main__":
path="/root"
os.path.walk(path,VisitDir,())
#如果能有人把这一段代码的作用是什么解释一下就好了


os.path.walk()与os.walk()产生的文件名列表并不相同.os.path.walk()产生目录树下的目录路径和文件路径,而os.walk()只产生文件路径
如下面的例程:
1 # -*- coding: utf-8 -*-
2 import os
3 for root, dirs, files in os.walk('/media/cdrom0'):
4 open('mycd.cdc', 'a').write("%s %s %s" % (root,dirs,files))
完成的功能是讲/media/cdrom0下的目录文件写入到mycd.cdc中。
代码解释:
1. 声明是 utf-8 编码文本;

2. 引入了 os 模块;

3. 使用os.walk() 扫描光盘,并返回三个对象;

4. 使用open()打开mycd.cdc 文件对象,并声明成追加模式,逐行记录以上三个对象。

2、符号链接

符号链接又叫软链接,是一类特殊的文件,这个文件包含了另一个文件的路径名(绝对路径或者相对路径)。路径可以是任意文件或目录,可以链接不同文件系统的文件。(链接文件可以链接不存在的文件,这就产生一般称之为”断链”的现象),链接文件甚至可以循环链接自己(类似于编程中的递归)。在对符号文件进行读或写操作的时候,系统会自动把该操作转换为对源文件的操作,但删除链接文件时,系统仅仅删除链接文件,而不删除源文件本身。
符号链接的操作是透明的:对符号链接文件进行读写的程序会表现得直接对目标文件进行操作。某些需要特别处理符号链接的程序(如备份程序)可能会识别并直接对其进行操作。
一个符号链接文件仅包含有一个文本字符串,其被操作系统解释为一条指向另一个文件或者目录的路径。它是一个独立文件,其存在并不依赖于目标文件。如果删除一个符号链接,它指向的目标文件不受影响。如果目标文件被移动、重命名或者删除,任何指向它的符号链接仍然存在,但是它们将会指向一个不复存在的文件。这种情况被有时被称为被遗弃。

引入:符号链接与快捷方式的区别

快捷方式(shortcut)是一种功能上类似符号链接的文件对象,但与符号链接有本质的不同。快捷方式是普通的文件(拥有扩展名 .lnk),而非符号,因此,快捷方式可以被复制、移动、更改(某些特殊的快捷方式无法更改所有信息)或删除。快捷方式可以指向文件、文件夹或其他任何系统中合法的位置(包括控制面板桌面等)。
快捷方式如果快捷方式指向可执行程序,则可以同时指定启动的命令行参数以及启动位置(对于非可执行程序的快捷方式也能指定这些信息,但无意义)。同时,可以为快捷方式单独选择图标(如果没有选择图标,则使用目标的图标),以方便用户个性化。
删除快捷方式完全不会影响被链接到的目标。如果删除了目标,则会使快捷方式失效。由于快捷方式可以使用相对路径绝对路径,因此移动快捷方式或目标可能导致快捷方式失效,也可能不会有影响。在某些Windows操作系统(包括但不限于Windows XP、Windows Vista)中,操作系统会对文件路径的改变作一定程度的自动处理,使得快捷方式将在大多数情况下能保持有效:当快捷方式指向的目标失效而目标被移动过时,系统将自动修改快捷方式的目标到新的位置。

其他的见《Python 核心编程2》9.7节

应用:

(1):检查下磁盘中(D)是否有文件"BeginMan"的文件夹,如果存在则新建"SuperMan",
            在该目录下创建一个名为"readme.txt"的文本文件,写入数据,然后输出文件内容
(2):如果文件夹BeginMan存在,则遍历该目录,并输入目录文件,
            如果该目录下存在文件,且如果有文件名为b.png,则重命名为boy.png,移到D盘根目录下
  (3):删除BeginMan目录下所有文件,只保留子目录

文件系统图如下:

D盘中并没有SuperMan的文件夹,这里程序如下:

复制代码
#coding=utf-8
import os,shutil
import datetime

DIR = 'D:\\'
FILENAME = 'BeginMan'
PATH = 'D:\\%s' %FILENAME
CONTENT = """
            (1):检查下磁盘中(D)是否有文件"BeginMan"的文件夹,如果存在则新建"SuperMan",\n
            在该目录下创建一个名为"readme.txt"的文本文件,写入数据,然后输出文件内容\n
            (2):如果文件夹BeginMan存在,则遍历该目录,并输入目录文件\n,
            如果该目录下存在文件,且如果有文件名为b.png,则重命名为boy.png,移到D盘根目录下\n
            (3):删除BeginMan目录下所有文件,只保留子目录
            ==============================================\n
            时间:%s\n
            作者:%s\n
            """ %(datetime.datetime.now(),FILENAME)

if FILENAME in os.listdir(DIR):
        print u'已经有同名文件:%s' %FILENAME
        for obj in os.listdir(PATH):
            print  u'%s\\%s\n' %(PATH,obj)
            try:
                if os.path.isfile(u'%s\\%s' %(PATH,obj)):
                    if obj == 'b.png':  #如果含有文件为b.png,则重命名为boy.png,移动到该目录上级
                        os.rename(u'%s\\%s' %(PATH,obj),u'%s\\%s' %(PATH,'boy.png'))
                        shutil.move(u'%s\\%s' %(PATH,'boy.png'), 'D:\\')
                    os.remove(u'%s\\%s' %(PATH,obj))#删除文件,只保留子目录
            except Exception,e:
                print 'The error:%s' %e
        FILENAME = 'SuperMan'
        os.mkdir('D:\\%s' %FILENAME)                    #创建目录
        f = open('D:\\%s\\readme.txt'%FILENAME,'w' )    #在该目录下创建文件
        f.write(CONTENT)                                #写入数据
        f.close()
        f = open('D:\\%s\\readme.txt'%FILENAME,'r' )
        print [lines.strip() for lines in f]            #输出
复制代码

运行如下:

效果如下:

Python有关文件、文件夹操作小结:

import os,shutil  #要用到这两个模块
 
<strong><span style="color: #0000ff;">创建文件:</span></strong>
1) os.mknod("test.txt") 创建空文件
2) open("test.txt",w)           直接打开一个文件,如果文件不存在则创建文件
 
<span style="color: #0000ff;"><strong>创建目录:</strong></span>
os.mkdir("file")                   创建目录
 
<strong><span style="color: #0000ff;">复制文件:</span></strong>
shutil.copyfile("oldfile","newfile")       oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile")            oldfile只能是文件夹,newfile可以是文件,也可以是目标目录
 
<strong><span style="color: #0000ff;">复制文件夹:</span></strong>
shutil.copytree("olddir","newdir")        olddir和newdir都只能是目录,且newdir必须不存在
 
<strong><span style="color: #0000ff;">重命名文件(目录)</span></strong>
os.rename("oldname","newname")       文件或目录都是使用这条命令
 
<strong><span style="color: #0000ff;">移动文件(目录)</span></strong>
shutil.move("oldpos","newpos")  
 
<strong><span style="color: #0000ff;">删除文件</span></strong>
os.remove("file")
 
<strong><span style="color: #0000ff;">删除目录</span></strong>
os.rmdir("dir") 只能删除空目录
shutil.rmtree("dir")    空目录、有内容的目录都可以删
 
<strong><span style="color: #0000ff;">转换目录</span></strong>
os.chdir("path")    换路径
 
<strong><span style="color: #0000ff;">判断目标</span></strong>
os.path.exists("goal")    判断目标是否存在
os.path.isdir("goal")     判断目标是否目录
os.path.isfile("goal")    判断目标是否文件   
<br><span style="color: #999999;">参考:http://www.cnblogs.com/phoebus0501/archive/2011/01/19/1939646.html</span>

 

 三、os.path

如下表:

 函数描述
 分隔  
 basename(p)  去掉目录路径, 返回文件名:
os.path.basename('D:\\Project\\python25\\Lib\\a.txt') #a.txt
 dirname(p)  去掉文件名, 返回目录路径:
os.path.dirname(D:\\Project\\python25\\Lib\\a.txt)
#D:\Project\python25\Lib
 join()  将分离的各部分组合成一个路径名:Django项目中常用,
复制代码
settings.py
DIRNAME = os.path.dirname(__file__)
TEMPLATE_DIRS = (
     os.path.join(DIRNAME, "themes"),
)
复制代码
 split()  返回 (dirname(), basename()) 元组:
>>>DIRNAME = 'D:\\Project\\python25\\Lib\\a.txt'
>>>os.path.split(DIRNAME)
('D:\\Project\\python25\\Lib', 'a.txt')
 splitdrive()  返回 (drivename, pathname) 元组:
os.path.splitdrive(DIRNAME)
#('D:', '\\Project\\python25\\Lib\\a.txt')
 splitext()  返回 (filename, extension) 元组
os.path.splitext(DIRNAME) 
#('D:\\Project\\python25\\Lib\\a', '.txt')
 信息  
 getatime(filename)  返回最近访问时间
gTime =  os.path.getatime(os.getcwd())
print gTime  #1372836299.77
tTime = time.localtime(gTime)
print time.strftime('%Y-%m-%d %H:%M:%S',tTime)  #2013-07-03 15:24:59
getctime(filename)  返回文件创建时间
cTime = os.path.getctime(os.getcwd())
c_time = time.localtime(cTime)
print time.strftime('%Y-%m-%d %H:%M:%S',c_time) #2013-04-17 17:27:46
 getmtime(filename)  返回最近文件修改时间
 getsize(filename)  返回文件大小(以字节为单位)
 查询  
 exists()  指定路径(文件或目录)是否存在
 isabs()  指定路径是否为绝对路径
 isdir()  指定路径是否存在且为一个目录
 isfile()  指定路径是否存在且为一个文件
 islink()  指定路径是否存在且为一个符号链接

 ismount()

samefile()

 指定路径是否存在且为一个挂载点

两个路径名是否指向同个文件

对上面不懂的地方的解释:

1、join()

把一个list中所有的串按照你定义的分隔符连接起来,比如:
list = ['a','b','c']
sep = '|'
join(list,sep)的结果就是a|b|c

W3中的解释:

定义和用法

join() 方法用于把数组中的所有元素放入一个字符串。

元素是通过指定的分隔符进行分隔的。

语法

arrayObject.join(separator)

参数

描述

separator

可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔符。

返回值

返回一个字符串。该字符串是通过把 arrayObject 的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入 separator 字符串而生成的。

实例

例子 1

在本例中,我们将创建一个数组,然后把它的所有元素放入一个字符串:

<script type="text/javascript"> var arr = new Array(3) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" document.write(arr.join()) </script>

输出:

George,John,Thomas

例子 2

在本例中,我们将使用分隔符来分隔数组中的元素:

<script type="text/javascript"> var arr = new Array(3) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" document.write(arr.join(".")) </script>

输出:

George.John.Thomas

posted on 2014-04-12 21:31  rednuo  阅读(137)  评论(0)    收藏  举报

导航