20.python的文件处理

  我们日常在处理文件的时候一般都遵循这样的逻辑:打开文件,操作文件,保存关闭文件。

  但在python中,又分为以下几步:创建文件对象,对文件对象进行操作(读入,写入之类的),关闭文件。

  由于文件操作在python2.x和python3.x中区别还是比较大的,3.x可以接受更多的参数。

  所以在此说明:以下内容都是针对python2.x而言的,准确来说是python2.7。

  下面来逐一分析:

1.创建文件对象

  创建文件对象的方法有两种,第一张是使用工厂函数 file(name[, mode[, buffering]]) -> file object ,另一种是调用内置函数 open(name[, mode[, buffering]]) -> file object 。

  两者其实并不存在本质上的区别,实际上 open 也是调用 file 实现的,但是python官方建议我们使用 open 进行文件对象的创建,所以我们也顺应官方的建议,下面的演示都是基于 open 来进行。

  首先,当我们使用 open 创新一个文件对象时需要一些参数,其中 name 是必须的,它接受一个字符串,表示文件名,文件名可以采用绝对路径,也可以采用相对路径,而 mode 表示模式,它接受一个字符串表示要用什么模式来创建这个文件对象,而模式的不同也会对文件造成影响,下面是一个关于模式的总结表:

文件模式 操作
r 以只读方式打开,默认
rU 或 Ua 以读方式打开, 同时提供通用换行符支持 (PEP 278)
w 以写方式打开 (必要时清空)
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打开 (参见 w )
a+ 以读写模式打开 (参见 a )
rb 以二进制读模式打开
wb 以二进制写模式打开 (参见 w )
ab 以二进制追加模式打开 (参见 a )
rb+ 以二进制读写模式打开 (参见 r+ )
wb+ 以二进制读写模式打开 (参见 w+ )
ab+ 以二进制读写模式打开 (参见 a+ )

  下面是关于这些模式的进一步解释:

  r : 顾名思义,同该模式创建的文件对象中的进行读取,而不能进行写入等操作,当要打开的文件不存在时抛出 IOError 异常。

  w:以只写的方式打开,该模式下,只能进行写入操作,而不能进行读取操作,如果打开的文件存在,则清空原文件再打开,若打开的文件不存在则创建该文件后再打开。这种模式相对危险,因为无论文件存不存存在,最后操作的都是一个空文件,此时写入会从头开始写,也就是文件指针在文件的开头处。

  a : 以追加的模式打开,该模式下不能进行文件的读取,但能进行写入操作。如果打开的文件存在,则打开此文件,将文件的指针移到文件的末尾,此时任何新写入的内容都会在文件的最末尾处。如果文件不存在,则新建一个文件,从头开始写。和 w 不同的是当打开的文件存在时不会清空原文件,只是进行追加写入。

  r+ :r 本身不能进行写入操作,而扩展成 r+ 之后,就能够进行写入了。r+ 打开的文件并不会清空文件,写入时其指针会在最开头,也就是我文件中的内容是 123456,我用 r+ 写入了 'abc' 字符串时,文件内容就变成了 abc456 了。同样的,文件不存在的时候还是会抛出异常。

  w+,a+:因为 w 和 a 都不具有读权限,所以在进行 + 号拓展后,都能进行读操作了,其他的行为了原来的一样。

  U :通用换行符支持,不同平台用来表示行结束的符号是不同的, 例如 \n, \r, 或者 \r\n 。但是如果只写了一种处理换行符的方法,在其他平台就无法同样了,如果要为每一个平台都写一个方法就太麻烦了。所以python在 Python 2.3 引入了 UNS。当你使用 'U' 标志打开文件的时候, 所有的行分割符(或行结束符, 无论它原来是什么)通过 Python 的输入方法(例如:read() )返回时都会被替换为换行符 NEWLINE(\n)。('rU' 模式也支持 'rb' 选项) 。 这个特性还支持包含不同类型行结束符的文件,文件对象的 newlines 属性会记录它曾“看到的”文件的行结束符。

  b:二进制模式,在 linux 中默认都是用二进制打开的,所以这个选项对 linux 而言可有可无,但如果真的需要使用二进制模式,还是建议写上,增加跨平台能力。使用此模式进行写入操作时,不仅可以写入字符串,还可以写入 buffer 对象。

  

  buffering 表示缓用于指示访问文件所采用的缓冲方式。 其中 0 表示不缓冲, 1 表示只缓冲一行数据, 任何其它大于 1 的值代表使用给定值作为缓冲区大小。不提供该参数或者给定负值代表使用系统默认缓冲机制,既对任何类电报机( tty )设备使用行缓冲, 其它设备使用正常缓冲。一般情况下使用系统默认方式即可。

  

  最后要总结一点,创建了文件对象,并不意味着读取了文件内容,这与我们日常生活中的打开文件的定义是不同的。Python的打开文件是获取了文件的句柄,也就是文件的操作入口,而读取文件内容还需要将其读入到python的内存中,也就是所谓的输入。


2.输入

  所谓的输入,就是将文件的内容读入的python中,有下面几种方法。

1. read([size]) -> read at most size bytes, returned as a string.

  如果 size(单位为字节) 是负数或者没有给,就一直读到EOF,也就是文件结束。返回一个保括所有内容的字符串(包括换行符)。注意,当在非阻塞模式下,数据就算低于要求也可能会返回,即使没有尺寸参数。

  这个方法是一次性读入,也就是加载1gb的文件就会直接占用1gb的内存,所以不适合读取大的文件。

f = open('test.txt')
a = f.read()
print a
print repr(a)

  文件内容:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAANEAAABhCAIAAADHktPNAAACpUlEQVR4nO3bQbKiMBhFYfY/7JW5h95Aj3vim1gWIvAU8OaPfKfuAChMJdapJCZx+ANkGf6luFwuV+B65RzScA5p2js3DMPK7dvt2fdxBCjh3J3J7bsC3d/fUwg+TWPnxpY8377XEm51Qvt+7phm7JAVYdo7NyzzdmPmRmfDazXaO/dQm5EcGyZzzx9hW0HaO/drP7fywv21yXRwXPgnvz1soYRzs9dbGsO5Hijh3FFTOs51QXvnbvWYGxw595WUcG5YWOng3FfSfk14dj63bYFjUpRVkpqU6OdwKjiHNJxDGs4hDeeQhnNIwzmkae/cznXg9dJQkBLOTU6I7N9v3VMIPk37fYjxxcom2K+HALjVC+37uWOa4Wx6P7R37qiDTFdn0zuhvXMPtXE2/QS0d+6Qfm4yHZw8RylKODd7vaUxnOuBEs4dNaXjXBe0d+5WD2fTT0MJ55ZWOlZ+h872hZzrgvZrwrPSbFvgmBRllaQmJfo5nArOIQ3nkIZzSMM5pOEc0nAOado7t3PvYb00FKSEc+P129k9hhc3ZJfe/+QXiLdpvw8xvljaBHupJdzqhPb93DHNcDa9H9o79+K4+VJjnE3vgfbOPdTG2fQT0N65138frLwwmQ5OnqMUJZybvd7SGM71QAnnjprSca4L2jt3q4ez6aehhHPDwkoH576S9mvCs/O58fP1wXdpOrhtdEaAEv0cTgXnkIZzSMM5pBmu//9mcrlcnh/epvmpOkiFcE7S4ZykwzlJh3OSDuckHc5JOpyTdDgn6XBO0uGcpMM5SYdzkg7nJB3OSTqck3Q4J+lwTtLhnKTj/xBIwzmk4RzScA5pOIc0nEMaziEN55CGc0jDOaThHNJwDmk4hzScQxrOIQ3nkIZzSMM5pOEc0nAOaX4AneQ3DVSzqmsAAAAASUVORK5CYII=" alt="" />

  代码输出:

aaarticlea/png;base64,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" alt="" />

  注意这里的换行符。文件中使用了3个回车,也就有3个换行符。

  我们在python的编码中使用过repr()函数来获取一个字符串的编码,这里我们使用这个函数,看看打开的文件都是什么编码。

  首先,我的编码声明为: # coding= utf-8

  aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtwAAAAjCAIAAAAokErbAAAELUlEQVR4nO3d7WGbMBCAYcZiIWscTWMtE4Zxf4BlfYIkhHrY7/MrcaLLHTroFVJ3egEAAAgw/e8EAAAAXi+GEgAAIARDCQAAEIGhBAAAiMBQAgAARGAoAQAAIjCUAAAAERhKAACACAwlAABABIYSAAAgAkMJAAAQgaEEAACIkBxKjJqUGZ0JAAAQaNxUkBlKZr24Lyx6Dl5p87txjJqm6XBT71eXvDh3zFlWHHqVXr1LHHp1WJxoKrhMYihJJdhW/aLnabOtvuVuZLiTY0mcaNJcT6jJPasK4qRXuQe5MJ/CyI3Hxyi32La6Ytdd6enV3PefyKfbnpZEpldr4/TKp28cMdfVz2Guyqcg8v16tVdjFCn9nZK23dDbEmNO7WqvfHrGMcrb5bLucLvCKDtEGOWeCLtxEqsWPW+LnVm2vq62fDKRolOgoa6ky6709Gqw4vhW7cg9LYlMr1bG6ZVPzzhCrqvP16LnyV5XT0wT39OrwxT/ouuJrBetjfPJN5w9Rk1KeSdD0Z3G3JBbPk2Eq/4a4xxHbp5utgjBCVBZV/Y7L74rTq/aNcfPj0fuaUlkerUpTq98OsQRdF11w56ZSr6oV0ep+Nc3zvFYZ7ZZL/4jve1+V1CcnetL49jbZt7AHN2BGhYnqmvd3bA/juJsJ5wTyN5Zq43jrsqcPG11teRzdFAb6yrfL6X1HLQdvdq7V5PpXLen9Cq9Wr4XV1xXP3dKFj27oX65V8eo+SfB3gFZHxos+mFTtrOWP5GF585hHPtl+4HtD39LBsUJ63o/1Yv64zifSRkvnk3L2/j9OOGq7FBSvV9t+SSOc+rgVNf1Ktsvo7bT5lzt2yp69XNUvV5N7/JFe0qv0qtVdV1xXf38aT4/HjO9OlDV+5QE+RkVTvyWW1xc0n4cN1KmTYfG8ep6ep/uj7FxnE8az71W24kTrnru3aCrrashnyDS7slTU1fxfuW+mV7t1qsmneFhnOY9LamLXqVXg6/2vK7mp6KGur6pV0eoe/M0J8H3RDbbjN1RbInGvfI47y/698/eH+lMd1wXJ1lXurSjfGa9bPH+Xsb7rads1wdxEqs+PyN6aFheV2s+yeOcPji1dZXtV/bkoVd79ap3p+Rcr3api16lV6++rj69zQoT+uVeHaDyHV23DI2a1ps7JvUsLfMArjzO+tn8eMzvJ1rvmTF8vjUmTlyXfSWebbNxjNZmXeZ0STqdvTiJVe+X4qd/VXW15RMd5z/nrwqZq0thXWX7tQbYPnR+IL0avHKmV5MZXren9Cq9+r+vq4mj3lbXl/Xq9WrfZt6Et5gaEYc4V8e5Y87E+c04d8yZOMS5BP/3DQAAEIGhBAAAiMBQAgAARGAoAQAAIjCUAAAAERhKAACACAwlAABABIYSAAAgAkMJAAAQgaEEAACIwFACAABE+AePtuevWCa43AAAAABJRU5ErkJggg==" alt="" />

  编码声明为: # coding= gbk

   aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsEAAAAiCAIAAAAxnJMmAAAEE0lEQVR4nO2d3ZmCMBBFUxYNmXJSjWlmKYZ9AGN+YTKAip7zpGguM5m7Yb6grpkAAAAA+jHvDgAAAAAuCT0EAAAAaKCHAAAAAA30EAAAAKCBHgIAAAA00EMAAACABnoIAAAA0EAPAQAAABroIQAAAEADPQQAAABooIcAAAAADfQQAAAAoMFMk7fG+nfHAQAAAB9AR1dgpsnbwY3xsdEN2REdv6vjrTFmswbXy+vzdK4Y82fp4FW8ehUdvPoynaIraGNqerpgRzeYhWX0JSevQdyXSXSKPm72v4n/CAQ69VHxJAvjESor58fbOFldXiXnLcx4tfX+HfEcVlOJMl7t1TkqnmN1PmZdfU5zVzwC5et5tS/g+uchdJPnliHe7yrCUfEcqeNtUhRZMeMiehuu+d7Gvl3VqYwa3bAMjjrF/rx08TSUCscq8qpy2sKMV7MR2/uWr6ypRBmvduocFc+ROh+yrt6n0Q0mrKs7Lv7f41U5jc9U7jjJ6JyPnnyD2b011ibeFW27tVpI+cU/H/Wn1NlWVjcji0Lm1868mu88eYsYr4Yx2/c+X1lTiTJeVekcFc8BOh+0rsaye5qIL/KqmOb3MqLw545ocGN6O2rZ/MliCV2zVCfsISXtaLEd8zKdIq+5GHk5t3SWv49IKGwz9erEoxpe1+WliWdrUpV5yetlnRsy2+HVo71aDee8muJVvCqvxRnr6nMfYnRDLPXLXhXS/m5nEv+8gz66WzhD6GTSfie3+qZOeDk8COVMZ/BFOnlejztSRTm34zHWJ3ohrKRO6zr5qGYP0V0vXTyVea5NTndek6xe3i4u35f7MgqvPmc18Wq9yifVFK/i1a68zlhXnxff4XYb8GoPK78Pkcl5m/fTgTiWMoJ1nVip4aqX6iR53ZOn601iqfMM477mjBWdfNR9bbeqNy9FPJnSqtd78hLXq/VmvHqYV309wk0ddU0leeFVvJq9euS62m5iFHl9k1dFrP3GVKT36HeGcIK40RmLZkqu83gx3Ux6PHKNYp6nU82rntpWPIMbF72/yScfsGmaNNOpjHqeo7jhJc9LG091nuuT05uXrF5Nr+PVo7ya7EPs8+oheeFVvHr2unpPipUH9MtelbD6O5WLoLdm3unwtftAjZtHcp352XC7DY+7MY+OLL838xqdMq9wpOwcmzreOT8Pi4paD2dNpzLqcai8c9WVly6eYp7/oka8sRgI85LVaxZYHkYnxKvZkT1erUZ4Xk3xKl5997pamXVdXl/mVQHrv3Xt8/0WJeigc7bOFWNG5zd1rhgzOujU4f9lAAAAgAZ6CAAAANBADwEAAAAa6CEAAABAAz0EAAAAaKCHAAAAAA30EAAAAKCBHgIAAAA00EMAAACABnoIAAAA0PAPR3Kj6FqN1d0AAAAASUVORK5CYII=" alt="" />

  发现无论编码声明是什么,返回的字符串都是一样的。说明编码声明并不影响从文件读取到的字符串的编码。

  那么,我们用 utf-8 编码写一个文件:

#! /usr/bin/env python
# coding= utf-8 f = open('test1.txt','w')
f.write('第一行\n第二行\n第三行\n')
f.close()

 再进行一下读取:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtcAAAAiCAIAAAAbLGKJAAAEIklEQVR4nO3dbWKjIBCAYY7FhcJxOE24TD2M/aEhfCoiQkze51eb1ukMjO6sdrNiBgAAGEGMTgAAAPwophAAADAGUwgAABiDKQQAAIzBFAIAAMZgCgEAAGMwhQAAgDGYQgAAwBhMIQAAYAymEAAAMAZTCAAAGEPMs1FCmdF5AACAD9B1KhDzbJTUk/vapGXwSp3fjWOUEGJ3F+9X1+fFuWPOnxWHXqVX7xKHXu0WJ5oKriRSGdWVO2kpVuvRt1z+DHc2LIkTzZLLGSTc06ggTvood5EL8ymMXLk+RrnF1tUVu+7STq/mvv9EPs32tCQyvXo0Tqt82sb5mOvqe5kP5VMQ+X692qoxSqV/L6Ru+fV6iDGntrFVPi3jGOVta1k7uG1glJ0ajHI7fzNO4qhJy/VgZ1o9XlddPplIUc9X1JV02aWdXg2O2L/72nNPSyLTqwfjtMqnZZwPua4+50lLYa+rJ8aH7+nVnjK/nXoizUlr43zyDaeLUUIpr/uLbh7mxtjy8SE86q8yzn7k6nFmjRB0/MG6st958Y1uetUes/8MuOeelkSmV6vitMqnQZwPuq66Yc+MIV/Uqx1l/42MswDLVCb15D+WW29hBdXYyb00jr0T5o3E0U2lbnGiupbtDBtiL856hjmB7M2yo3HcozJnS11dNfnsLWplXeX7pbSWQdvRq617NZnOdXtKr9Kr5XtxxXX1fS9k0tIN9cu92k3+X+p6K7A8B5j0w+Zopyl/5gpPlt049sv2A9sQ/h50ihPW9XoyFzXEfj5CGS+eTcvb6e044VHZKeTwftXlk1jn1OIcrmsu2y+j1vPkXO3rUfTqe1W9Xk3v8kV7Sq/Sq4fquuK6+v7jWz4ekl7ta+P9QoKEjApnesutJq5hO44bKdOXXeN4dT29T7cH1TjOO43nVm9txAmPem7dcztaV0U+QaTNs+VIXcX7lftmerVZr5p0hrtxqve0pC56lV4Nvtryupofgyrq+qZe7WTrXcucjF4zl7QpusPWFA105XFeX/Rvib0+0pl2uC5Osq50aXv5SD2t8f5m4/2qUrbNgziJo94/I3rwV15XbT7JdU4vztG6yvYre7bQq6161bsXcq5Xm9RFr9KrV19Xn95mhQn9cq/2sfneqWtKRonlfo1JPQ/LPEQrj7N8Jh8P+Xoq9ZoKw2dUfeLEddlX4uk1G8dobZbDnLZIp7MVJ3HU66X4Cd6huuryidb5z/nLQOZyUlhX2X4tAdYPnR9IrwavnOnVZIbX7Sm9Sq+Ovq4mVr2uri/r1S6238HdhHeNKhGHOFfHuWPOxPnNOHfMmTjEuQr/jwwAABiDKQQAAIzBFAIAAMZgCgEAAGMwhQAAgDGYQgAAwBhMIQAAYAymEAAAMAZTCAAAGIMpBAAAjMEUAgAAxvgHqmNfqy4Vjy0AAAAASUVORK5CYII=" alt="" />

  和上面的一样。

  再用gbk写一个文件:

#! /usr/bin/env python
# coding= gbk f = open('test2.txt','w')
f.write('第一行\n第二行\n第三行\n')
f.close()

  再读取一下:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfcAAAAfCAIAAAB1dxMrAAADmklEQVR4nO2c0ZWsKhBFDcuEmjxeAkTTJHMNpt+HooUgWkj3CGvvr1kKx1OWFMI4M3wAAKBfhr82AAAAX4QqDwDQM1R5AICeocoDAPQMVR4AoGeo8gAAPbNWeWcG4/7SCQAAfKpXY1HlRzvJM5Mdd0cSVobh1M25jmx6LPg7nTiuVKTtxdViTmv7me0cKZLTfJutaZXYK/lJ5FQ4bDGncTW+x1LlU1e+Ymc35/j7PbP0VqU9M4kV6QhHXrcgruSRsri8oa3rL3VazGmi++pJk9Oln3EZS+RU67nMT0qvZJx+jnMq72pbOa01T27k9uUvXG3/9DiXaK9xnVuqaHXen8m+fAdn1udHH1faWEFckx0XFTFb/1KnwZxG3Z3xY2Y7dc3P+UKYnKo8l/qJ1XwP3TjNONE+G0GvP89pXbK/fb20GDx/ejRhZcehUucdqImf1XEdGFP7kR3K0n5bp72cxu+hqQ4XF8I1Ny7IabGfTAftPTyv8k3mtCon39iIWzWvqUY7yW0+ZwZjzLoicfb1GsN14DWd9fA4ihk4XMEV6ny8mjSkjCt5RO3ncNb5oo6xdlR6flpO936MD0qlE25SiPF/Ly5yWjhO993WLZtg2JbkNFUBWsxpRc6+pAy8zesPsQ2yrq98EXVW7JAcPIYpHd9/3WTbOoRztVpHHi2PK3VE7SeT9e/oOCMq4+VrPS2ngZ9/W1DaXETX3fqHv+wip9c83xun83nfzpm5+X6oFuc0rABN5rQep9/L7y589FDE/uKOSp11dr+ns2tRqnMUqULncAX3LZ0Knp+W07fY6lT6STaI3gRL/JDT4nuYCfCKTqZ9B+O0Gud/FSWu7OeuYJj5uWt+zxJB7dKR1VnfMcywC3g3Jyt1wnP2sk4Q15Q+cs9P9K3UF3QOn56mcrq/85sLXS7i+yD6TxM5LfB8Y5wuZydr30JOqRPfh9hhSVwPyWktLvzt63JpZ5Z9Iyf3+6x18+bYGoyf2KMX6JyO7zhvHq4hD8Mwvl5jcg/ygs7rP/GyFjlSxZU4UhbXFH1Z9U2dufHyozDeUk7jO7/ux2r8TNsm7tZtSm0qk9OfjVO5+VbgJ5nT2GG7Oa3Elf9wEE33haDzHJ0WPaPznGuh8xydc/g/NgAAPUOVBwDoGao8AEDPUOUBAHqGKg8A0DNUeQCAnqHKAwD0DFUeAKBnqPIAAD1DlQcA6BmqPABAz1DlAQB6hioPANAz/wNimAKzPVYLFwAAAABJRU5ErkJggg==" alt="" />

  结果不同了。

  说明一个问题:在文件对象中读取获得的字符串,其编码和python的编码声明无关,只与文件本身保存时使用的编码有关。

  python的编码声明只影响在python创建的字符串,所以我根据这个特性,在python创建相应编码的字符串,再保存到文件中,所有文件内字符的编码才会不一样,希望大家不要绕晕了。

  讲到这里,就可以看python中是如何进行文件的编码转换的了。

  编码的转换其实是针对于字符串的,所有用到的也是字符串中的内置方法:

S.decode([encoding[,errors]]) -> object

  该方法返回解码后的字符串。

  encoding -- 要使用的编码,如"UTF-8"(默认)。errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。

  代码示例:

f = open('test2.txt','r')
a = f.read()
b = a.decode(encoding='gbk')
print b
print repr(b)

aaarticlea/png;base64,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" alt="" />

  可以看出,进行解码以后得到的是Unicode字符串。

  接下来我们看看如何编码。

S.encode([encoding[,errors]]) -> object

  该方法返回编码后的字符串。

  encoding -- 要使用的编码,如"UTF-8"(默认)。errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。

  代码示例:

f = open('test2.txt','r')
a = f.read()
b = a.decode(encoding='gbk')
c = b.encode(encoding='utf-8')
print c
print repr(c)

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAucAAAB9CAIAAACOB1qTAAAIhUlEQVR4nO3dQXqqPBgGUJbFhsoy2h0w6yo6LfO7iju47KBb+Af+A5UiBAgBrKnnPAyqhY8Eor4laosTAEAOip9uAABAFKkFAMiD1AIA5EFqAQDysJxaiqKYubl6f9s2BwCeVlRq6Qxuro0g3fpbigAAz2khMfRzxvjmuj1JJwDABndKElviDgDAae0M0caZneAck0kiACBG4htTTuuvmgTTibwCAETa4VrLzArdaoO3xfSL790jAOB3WvfJ540hQ2oBAJJtutaSMEm0eA8AQFBsaAhO8UgtAMDdRIWGYuJzy1ILAHA3y98yF3xfS9rHlQelfOYZAIgnNAAAeZBaAIA8SC0AQB6kFgAgD1ILAJAHqQUAyIPUAgDkYd3/IRrfXL0/X9ACACRZ93+IBjeTvxt3SxEA4Dktfzdu/4eZr/Zf/PeK0gkAsMWdksRU3AEAiLRuhmjjzE5wjskkEQAQI/2fNie8qWW8ibwCAES607WWwdtiBvcDACxa98nnjSFDagEAkm261pIwSbR4DwBAUGxoCE7xSC0AwN1EhYapzy3PfCYoeD1GagEAki1/y1wwdqR9XHlQymeeAYB4QgMAkAepBQDIg9QCAORBagEA8iC1AAB5kFoAgDxILQBAHtb9H6LxzdX78wUtAECSdf+H6DT6JtzxOjP/qGhq/b07BQD8Qsvfjdv/Yeqr/aP2JJ0AABvcKUlsiTsAAKe1M0QbZ3aCc0wmiQCAGOviQjH7D5wXtx1vIq8AAJF2u9Yyv8*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" alt="" />

  得到的就是 utf-8 编码的字符串了,也就是完成了gbk-->Unicode-->utf-8的转换了。此时可以看看我在python的编码中的内容,就明白了Unicode作为桥梁的含义了。

f = open('test2.txt','r')
a = f.read()
f.close()
b = a.decode(encoding='gbk')
c = b.encode(encoding='utf-8')
f = open('test2.txt','w')
f.write(c)
f.close()

  使用以上的代码就可以完成文件的编码转换了,当然还有一定的优化空间,这里仅作为逻辑演示。

  接下来继续进行输入方法的说明。

2. readline([size]) -> next line from the file, as a string.

  一次读取一行,保留换行符,返回一个字符串对象。size(默认为 -1, 代表读至行结束符)为非负数时,用来限制最大读取的字节数,当字节数设置少于真正一行的字节时,会返回不完整的一行,超过时不影响。当为EOF也就是文件结束时,返回空字符串。配合for循环使用可以进行逐行遍历。由于返回的也是字符串,所以也可以进行对返回对象使用字符串的方法,例如编解码等。

f = open('test2.txt', 'r')
for x in range(2):
print f.readline()

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAABTCAIAAACtXnOXAAACXElEQVR4nO3dQXKiQACG0T6WJ+IY5gbZzSlm7T6ncJMb5BKZTcayAMEGAm39762CUcAqPmlsqyjfm7l25c/758N/X7q/l+02tshtD69dGdmZBvZwW1/vp3O301vac1ut2fC9jx+ZT/n8ONW8tizbSo1rV86lvLVzWFy6cylv5fTx/2OquT0k0+DIfMbP0Vsmz7tDO5QPNEf5kEj5kEj5kEj5kEj5kEj5kGim/FLKxGL1xta9HNjKfPk3vcXajG/PX7MSYBNT4d23Olys24zCoSV7BLnmIwP4DRWj/ZWj9NHrBQN+OERFdfeJLrjIH75E83CUtef8iSfcntb7muB+5b/wjoB5FbN6K0NVPrRj+Tl/wYB/9hFgH0+1NzpcVz68rvn2yoM5OeXD65r5Jc/odf6yqbjeqsznwYG0B4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4mUD4kq7qI9XKzemNtpQRsq7qLdW1x8R801KwE2MXNHzfs/Jm6q+8hwVUAL9gjy0UcGcJSK0f7KUfro9YIBPxyioro1o/fRwjUPR9njnN/7mqD3OLC/ilm9laEqH9qx/Jy/YMA/+wiwj6faGx2uKx9e13x7j+bkJr6rHx0XKB/aMfNLntF0l03F9VZlPg8OpD1IpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxIpHxI9A/c6b6vakufTgAAAABJRU5ErkJggg==" alt="" />

  由于print关键字会默认添加换行符,而文件中已经又换行符了,所以会出现两个换行符,也就出现了输出这样的隔行显示。可以加入一个逗号取消print这种默认行为。

f = open('test2.txt', 'r')
for x in range(2):
print f.readline(),

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKEAAAAtCAIAAABJQZxCAAABZ0lEQVR4nO3aQZKCMBCF4T7WnIhj6KnczylmM4fBzWhhQhITSPf46v92UhCxnyQibessP4tdzK7Lbdo7dLotF7OrfX3//m34d2c4iUWfAKYjY31krI+M9UVmbGZmfMmmI2N9ZKxvv8RJ6Q8mUTqcjH3Uqv/MwF71vcFj/3wQMvaxU+JtKvnLvtGrh5Cxj4klbn45yNhHe64+MlGvm8ngrAHRq13ibQwDi3F+SLJCdw2IAYPXcWWH5272upxvB98OMuuT4aF973QwBjIO130dD0zXpS1k7KNxb7NmIZHxxymW2Ap3PmT8cfb/A9ldj8ciSYbKf7j1DohePJPQR8b6yFgfGeujxPrIWB8Z64vs9YGPyF4f+Bjv9Sk+sjjvmRVOEdnrAx+RvT5Hzx3viez1gY+J13GynCfb4Say1wc+Int94COy1wc+Bnt96hd6faonY2eRvT7wQbn1kbE+MtZHxvrIWB8Z67sD6bOFiyjJPY8AAAAASUVORK5CYII=" alt="" />

  另外,还有注意一个问题,不用想下面这里循环:

f = open('test2.txt', 'r')
for x in f.readline(): #相当于读取一行,对每个字节进行遍历
print x #此时打印的就是一个字节,utf-8中,显示中文需要3个字节,输出的就是乱码了
print repr(x) #看一下是否是字节

aaarticlea/png;base64,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" alt="" />

  每次读取一行,内存消耗自然就低了点,但是很难知道文件有多少行,所以也不是一个理想的遍历方式。

3.  readlines([size]) -> list of strings, each a line from the file.

  方法并不像其它两个输入方法一样返回一个字符串, 它会读取所有(剩余的)行,然后把它们作为一个字符串列表返回。 它的可选参数 size 代表返回的大字节大小。如果它大于 0 , 那么返回的所有行应该大约有 size 字节(可能稍微大于这个数字, 因为需要凑齐缓冲区大小。比如说缓冲区的大小只能为 4K 的倍数,如果 size 为 15k,则后返回的可能是 16k)。

  因为返回的是一个包含所有行的列表,所以可以直接对其进行遍历,注意和上面的区别。

f = open('test2.txt', 'r')
for x in f.readlines():
print x,

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYIAAABXCAIAAACGHNX2AAAG4ElEQVR4nO3cy7WrNhSAYZVFCWnkqAxcQZh5lHTA9GjuKpjQQJ*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" alt="" />

  但是,它也是一次性读取了整个文件,所以内存占用也是非常大的。

  此时,有一个更高效的 xreadlines 方法,参数也是一样的,只不过其本质是一个生成器,也就是每次调用都返回一行,迭代的时候是逐行读取,效率更高。

  但是,这并不是最好的方法,最好的方法是直接迭代文件对象:

f = open('test2.txt', 'r')
for x in f:
print x,

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW0AAABBCAIAAACVemKMAAAEuUlEQVR4nO3cy5WjOBSAYYVFCJNIKQwcQWvn3WTAtrV3FGxIYI6T0CwAoRcqzIW26fq/hU/ZLfTmInBb6r+Y20arzm5Majul+/lNnx3Y6+YxjAnN9EeWrNeqbcwz+PxpmrsZnBsezXR4nsY55wZzb8wzrs/DDC7+JKlhq22c85k1jM1HLYU+TdNZ9zRfvug8TaKSf15cq5ek/sD8j0oNe61aFdWkWIGkrCkfq9t5gIIeU91v12t1N4N/9Rl+2/PFNHl9CvmstKKSc3mUVTouUdutHhve2aG3Q61X03lY+iQuK69PXu3iHBurV2lp2ookjdoXR+aqOOecG56l2VxsQ2FEp1PddqUJnbx96Y9wji6srk+pQj7n1bDUV61SN6VuKqpS0NvlNKHn1tGx3bYzp1VLBfLS187S8KhiWXM+y1mxZPh7ehu+JpWs1zm7XCX12RJrbFcai43jHucTtt12jXlo1aq0k4u9+tJEWvunfEC3jGD8YTqCUZqdcSS4zvd6uZiXWe3D2OqVShWbbfuVjiteB6I0g7n7034wj0ogy2qYR/RTalgShIDp/J/XI01+PVmNEdtGp3h5WVYEY1WNzydp11J6YTaXjorLGh5fc4gfr89LzrZTB8eRvD5ufQSznJfeyI+qjHK9n1ttkgmW92qe85aytq9Hwjk21bBwpiwtTVoRpdkZR+ZT61Y+uxLTjcN8SL4at128cJhT6n4Jn7qfrw9+dP0VJk/z7z9L0A1LrNdwTHBvmlapW9Rrx9fQnyqx6agg5+YxTIfPiaM0RRtGp3B5cYO5jz02t93nE5QVlr5csW9B/2RHlRcjYc+M07FT6qZ0p1Wrml9K3bTu/Ou4JPTFzevwrFfTNCutCEew3Iq5Pk331fjbh3Dcw97wETDLp9TPVnfWPa0NykrHtDemN9E8jGfmWp2jWbcy9Pn8mXMrDGJ5BNM0u+PIS5KVeap0r/GH+RquLVjeXsNjFS8vf0FZn+bAtleWsd+JllQ7fN+KPxNH1kzXk8+ZZFYnK6aPqyF+pmxmbuEfhdSu4od4bxwB8DcgjgCQIo4AkCKOAJAijgCQIo4AkCKOAJDaH0eUUpW3L9dDdjiANxLFES95+2pQ8OklmQB4l51xJDzz87ev1YB4AVzcm5+PSAIQgA9xzH2N8H6keGfErQ1wFcesR8ITfsfDkfwQIghwISeuRyoJfLLk8UqY+UENBHC6Y773FZ72xBHg0k5Zj+y4tfn2EwAfS/p8pHhjQhwBfhRRHFEr39oSR4AfZf//Qys+H9n3ZW2SFd/4AtfC7/QASBFHAEgRRwBIEUcASBFHAEgRRwBIEUcASLGvIgAp9lUEIHXuvopbfshHvACujn0VAUixryIAKfZVBCD15vVI8ngl+RzAJbCvIgAp9lUEIMW+igCkTtxXsb5gqd8WEUeAC2FfRQBS/E4PgBRxBIAUcQSAFHEEgBRxBIAUcQSAFHEEgBT7KgKQOndfxY0/wFlLf1AbAZzr3H0VX8oKwEWxryIAKfZVBCDFvooApE5fj9QTJI9Xks8BXAL7KgKQYl9FAFLsqwhA6sR9FXfkszsHAG904r6K9Ruftccr++6MALwRv9MDIEUcASD1P2BRezNexsGkAAAAAElFTkSuQmCC" alt="" />

  这是自python2.2中引入的迭代器和文件迭代后的新特性,文件对象成为了它们自己的迭代器,这意味着用户不必调用 read*() 方法就可以在 for 循环中迭代文件的每一行。 另外我们也可以使用迭代器的 next 方法, file.next() 可以用来读取文件的下一行。和其它迭代器一样, Python 也会在所有行迭代完成后引发 StopIteration 异常。但 for 循环会自动调用 next 方法和处理迭代完成后引发的异常,所以直接迭代文件对象成为了最佳的用法。

  另个废弃的方法是 readinto() ,它读取给定数目的字节到一个可写的缓冲器对象,和废弃的 buffer() 内建函数返回的对象是同个类型。(由于 buffer() 已经不再支持,所以 readinto() 被废弃。)


3.输出

1. write(str) -> None. Write string str to file.

  向文件中写入字符串,这里不再演示了。

2. writelines(sequence_of_strings) -> None. Write the strings to the file.

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

  注意这里并没有 "writeline()" 方法, 因为它等价于使用以行结束符结尾的单行字符串调用 write() 方法.


4.文件内指针的移动

  文件内的指针相对与我们平常所见的光标,它表示我们各种操作的位置。例如我们用 r+ 打开文件并写入东西时,光标就在文件的开头,所以出现开头举例的会覆盖原有字符的现象,而 a 模式打开后光标在文件的最后,所以在 a 模式下写入内容会在文件的末尾追加。

1. seek(offset[, whence]) -> None. Move to new file position.

  在文件中移动光标的位置 从 whence ( 0 代表文件起始; 1 代表当前位置,当前位置由打开模式决定,或者之前有移动过光标; 2 代表文件末尾)偏移 off 字节 ,off为正时向右移动,为负时向左移动。当光标在文件开头时,只能为正;在文件末尾时,只能为负。虽然部分文件支持光标超出末尾,但还是不超过的好。

2. tell() -> current file position, an integer (may be a long integer).

  返回一个整数(有可能是长整数),表示当前光标所在的位置。

3. truncate([size]) -> None. Truncate the file to at most size bytes.

  截取文件到大 size 字节, 默认为当前文件位置(size=file.tell())。所谓的截取就是光标前面的保留,后面的全部去掉。


5.关闭保存

1. close() -> None or (perhaps) an integer. Close the file.

  关闭文件。如果文件不关闭,则对文件的各种操作都保存在缓冲区中,关闭文件才能把缓冲区里的内容写入磁盘中。

2. flush() -> None. Flush the internal I/O buffer.

  在不关闭文件的前提下,将缓冲区里的内容保存到磁盘中。


6.其他方法

1. isatty() -> true or false.

   判断 file 是否是一个类 tty 设备

2. x.next() -> the next value, or raise StopIteration

  返回文件的下一行(类似于 file.readline() ), 在没有其它行时引发 StopIteration 异常。


7.file对象相关属性

  file.closed         True 表示文件已经被关闭, 否则为 False

  file.encoding     文件所使用的编码 - 当 Unicode 字符串被写入数据时, 它们将自动使 用 file.encoding 转换为字节字符串; 若 file.encoding 为 None 时使用系统默认编码

  file.mode          文件打开时使用的访问模式

  file.name          文件名

  file.newlines     未读取到行分隔符时为 None , 只有一种行分隔符时为一个字符串, 当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束符的列表。

  file.softspace   为 0 表示在输出一数据后,要加上一个空格符,1 表示不加。这个属性一般程序员用不着,由程序内部使用。


  关于文件操作就先总结到这,有什么错误或补充的以后会进行修正。

上一篇:MVC请求管道


下一篇:有关web 语义的文章总结