十四、文件
说明是文件? linux下一切皆文件 。
常见文件格式 : .exe 、 .txt 、 .ppt 、 .jpg 、 .mp4 、 .avi ......
1. 如何打开文件并且获取文件描述符?
一般使用 f = open( 文件路径, 打开方式) 的形式打开。
print(help(open))
输出 :
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
...
========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' create a new file and open it for writing
'a' open for writing, appending to the end of the file if it exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
'U' universal newline mode (deprecated)
========= ===============================================================
...
我们一般只会用到前两个参数 :
file : 文件路径
mode : 打开方式
打开方式和意义如下:
type info
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。
如果该文件不存在,创建新文件进行写入。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,
新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
用的最多的打开方式为 : 只读( r )、只写( w , 不存在则创建,存在则覆盖) 在末尾追加( a )
看看文件描述符有哪些方法可以用 :
f = open('./test.text', 'w')
print(dir(f))
f.close()
输出 :
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__',
'__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__',
'__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing',
'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode',
'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable',
'write', 'writelines']
最常用的有 :
1. close() 关闭文件描述符,并且把缓冲区里面的内容保存到文件中(如果不调用 close , 那么数据就不会被保存到文件中!!!)
f.close()
2. read(size) 读取文件中的 size 个字符返回到一个字符串中
print(f.read(7))
3. readline(size) 按行读取,读取文件中某一行的 size 个字符返回到一个字符串中
print(f.readline(7))
4. write() 向文件写入字符串
f.write('hello')
5. writelines() 向文件写入字符串序列 seq, seq 应该是应该返回字符串的可迭代对象。
f.writelines(['hello', 'word', 'zzz'])
6. seek(offset(偏移多少个位置), from(从哪里开始偏移))
f.seek(9, 0)
7. tell() 返回文件指针当前在文件中所处的位置(一个数字)
print(f.tell())
可以直接对文件描述符进行迭代(按行),这样读取效率就比较高。
f = open('./test.text', 'r')
for each_read in f:
print(each_read) 一次 打印一行
2. 一个牛X的模块: os
因为不同的平台他的底层驱动不同, 所有对文件的操作方式也不一样。 但是我们的 python 是属于跨平台的,同样的代码,
在 linux 能用, 当然希望在windos 也同样能用。 这就有了我们的 os 模块。
OS : Operating System
对于文件系统的访问来说, python 调用 os 模块就可以了(板块胡帮我们识别并调用对应的函数等 )。不需要考虑操作系统。
import os
print(dir(os))
输出 :
['DirEntry', 'F_OK', 'MutableMapping', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY',
'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO',
'P_OVERLAY', 'P_WAIT', 'PathLike', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'W_OK', 'X_OK', '_Environ', '__all__',
'__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_execvpe', '_exists',
'_exit', '_fspath', '_get_exports_list', '_putenv', '_unsetenv', '_wrap_close',
'abc', 'abort', 'access', 'altsep', 'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'curdir', 'defpath', 'device_encoding',
'devnull', 'dup', 'dup2', 'environ', 'errno', 'error', 'execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp',
'execvpe', 'extsep', 'fdopen', 'fsdecode', 'fsencode', 'fspath', 'fstat', 'fsync', 'ftruncate', 'get_exec_path',
'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 'getenv', 'getlogin', 'getpid',
'getppid', 'isatty', 'kill', 'linesep', 'link', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir',
'path', 'pathsep', 'pipe', 'popen', 'putenv', 'read', 'readlink', 'remove', 'removedirs', 'rename', 'renames', 'replace',
'rmdir', 'scandir', 'sep', 'set_handle_inheritable', 'set_inheritable', 'spawnl', 'spawnle', 'spawnv', 'spawnve', 'st',
'startfile', 'stat', 'stat_float_times', 'stat_result', 'statvfs_result', 'strerror', 'supports_bytes_environ', 'supports_dir_fd',
'supports_effective_ids', 'supports_fd', 'supports_follow_symlinks', 'symlink', 'sys', 'system', 'terminal_size', 'times',
'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 'urandom', 'utime', 'waitpid', 'walk', 'write']
os 模块常用的函数等 :
os.sep:取代操作系统特定的路径分隔符
os.name:指示你正在使用的工作平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。
os.getcwd:得到当前工作目录,即当前python脚本工作的目录路径。
os.getenv()和os.putenv:分别用来读取和设置环境变量
os.listdir():返回指定目录下的所有文件和目录名
os.remove(file):删除一个文件
os.stat(file):获得文件属性
os.chmod(file):修改文件权限和时间戳
os.mkdir(name):创建目录
os.rmdir(name):删除目录
os.removedirs(r“c:\python”):删除多个目录
os.system():运行shell命令
os.exit():终止当前进程
os.linesep:给出当前平台的行终止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'
os.path.split():返回一个路径的目录名和文件名
os.path.isfile()和os.path.isdir()分别检验给出的路径是一个目录还是文件
os.path.existe():检验给出的路径是否真的存在
os.listdir(dirname):列出dirname下的目录和文件
os.getcwd():获得当前工作目录
os.curdir:返回当前目录('.')
os.chdir(dirname):改变工作目录到dirname
os.path.isdir(name):判断name是不是目录,不是目录就返回false
os.path.isfile(name):判断name这个文件是否存在,不存在返回false
os.path.exists(name):判断是否存在文件或目录name
os.path.getsize(name):或得文件大小,如果name是目录返回0L
os.path.abspath(name):获得绝对路径
os.path.isabs():判断是否为绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(name):分割文件名与目录(事实上,如果你完全使用目录,它也会将最后一个目录作为文件名而分离,同时它不会判断文件或目录是否存在)
os.path.splitext():分离文件名和扩展名
os.path.join(path,name):连接目录与文件名或目录
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径
【 os 最常用方法 】
1. getcwd() : 获取当前工作目录(当前python脚本工作目录)
print(os.getcwd()) C:\Users\14565\PycharmProjects\untitled
2. chdir(path) : 改变当前工作目录
import os
print(os.getcwd()) C:\Users\14565\PycharmProjects\untitled
os.chdir(r'C:\Users\14565\PycharmProjects')
print(os.getcwd()) C:\Users\14565\PycharmProjects
3.listdir(path) : 列举指定目录中的文件名
print(os.listdir(r'C:\Users')) ['14565', 'All Users', 'Default', 'Default User', 'desktop.ini', 'Public']
4. mkdir(path) : 创建单层【目录】, 如果目录已存在就会抛出一个异常。
os.mkdir('b')
5. makedirs(path) : 递归创建多层【目录】 ,如果最后一层的子目录已存在,则会抛出一个异常
os.makedirs(r'a\b\c\d')
FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: 'a\\b\\c\\d'
6. remove(path) : 删除【文件】
os.remove(r'test.text')
7. rmdir(path) : 删除单层目录, 目录不存在则抛出异常
os.rmdir(r'a\b\c\d')
8. removedirs(path) : 递归删除目录,从子目录到父目录尝试逐层删除, 遇到目录非空则抛出异常
os.removedirs(r'a\b\c')
9. rename(oldname, newname) : 对单个文件进行重命名
os.rename(r'a\b\c\d', r'a\b\c\e')
10. system(shell) : 运行系统的 shell 命令
os.system('dir')
11. curdir : 代指当前目录的 (.)
print(os.curdir) .
12. pardir : 代指上一级目录 (..)
print(os.pardir)
13. sep : 输出当前操作系统特定的路径分隔符 (windos 为 '\', linux 为 '/')
print(os.sep) \
14. linesep : 当前平台使用的 行终止符号 (windos 为 '\r\n', linux 为 '\n')
print(os.linesep)
15. name : 代指当前使用的操作系统(包括 : 'posix', 'nt', 'mac', 'os2', 'ce', 'java'))
print(os.name)
16. exit()
os.exit():终止当前进程
【 os.path 关于路径最常用方法 】
1. basename(path) 去掉目录路径, 单独返回文件名
print(os.path.basename(r'a\b')) b
2. dirname(path) 去掉文件名, 单独返回目录路径
print(os.path.dirname(r'.\a\b'))
3. join(path1, path2) 将 path1、path2各部分组合成一个新的文件名
print(os.path.join(os.path.dirname(r'.\a\b\c'), 'wwc')) .\a\b\wwc
4. split(path) 分割文件名与路径, 返回 (f_name, f_extension) 元组
print(os.path.split(r'a\b\c\e'))
=========================================================================
十五、存储对象
我们一般的列表、元组、字典。。。。大多都是在程序中定义, 然后再内存中存储, 程序结束后他们也就消失了。
有没有办法把他们永久的储存起来呢? 有的, 使用我们的 pickle 模块
用法如下 :
import pickle
my_list = [1, 5, 'hehe', ('啊?', 'hello')]
pickle_file = open('my_list.pkl', 'wb') 以打开二进制文件进行写入的方式打开一个文件(一般为了方便识别, 以 .pkl 作为文件后缀)
pickle.dump(my_list, pickle_file) 调用 pickle.dump() 方法将对象存储到文件描述符
pickle_file.close() 关闭文件
此时就会生成一个 my_list.pkl 文件, 他是以二进制的形式存储的, 所以用 pycharm 直接打开会是乱码。
pickle_file2 = open('my_list.pkl', 'rb') 以打开二进制文件进行只读的方式打开这个pkl文件
my_list2 = pickle.load(pickle_file2) 调用 pickle.load() 方法将文件描述符中存储的对象取出来作为返回值
print(my_list2) [1, 5, 'hehe', ('啊?', 'hello')] 打印这个返回值。
关键点 :
1. 存储的时候要先生成一个文件描述符。 然后调用 pickle.dump() 方法 把对象写入文件描述符
2. 取出数据的时候, 要先通过文件描述符打开这个文件, 再调用 pickle.load() 方法把对象从文件描述符取出来
使用场景 :
比如当我们的列表特别大的时候,直接写到程序里面会显得非常臃肿, (在使用django录入初始数据而初始数据特别大的时候),
就可以使用 pickle 把这个对象存储到一个文件中。