Python - with open()、os.open()、open()的详细使用
<h2>读写文件背景</h2><p>读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。</p>
<p>在磁盘上读写文件的功能都是由操作系统提供的,<span style="color: rgba(210, 44, 74, 1)">现代操作系统不允许普通的程序直接操作磁盘</span>。</p>
<p>读写文件就是<span style="color: rgba(210, 44, 74, 1)">请求操作系统打开一个文件对象(通常称为文件描述符)</span>,然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。</p>
<p> </p>
<h1>open()、with open()</h1>
<h2>打开文件</h2>
<p>要以读文件的模式打开一个文件对象,使用Python内置的 <span class="cnblogs_code">open()</span> 函数,传入文件名和标示符:</p>
<p><span class="cnblogs_code">f = open(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/Users/michael/test.txt</span><span style="color: rgba(128, 0, 0, 1)">'</span>, mode=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</span> </p>
<p>标示符 <span class="cnblogs_code"><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span></span> 表示只读,这样,我们就成功地打开了一个文件。</p>
<p>如果文件不存在, <span class="cnblogs_code">open()</span> 函数就会抛出一个 <span class="cnblogs_code">IOError</span> 的错误,并且给出错误码和详细的信息告诉你文件不存在:</p>
<div class="cnblogs_code">
<pre>>>> f=open(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/Users/michael/notfound.txt</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
Traceback (most recent call last):
File </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"><stdin></span><span style="color: rgba(128, 0, 0, 1)">"</span>, line 1, <span style="color: rgba(0, 0, 255, 1)">in</span> <module><span style="color: rgba(0, 0, 0, 1)">
FileNotFoundError: No such file <span style="color: rgba(0, 0, 255, 1)">or</span> directory: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/Users/michael/notfound.txt</span><span style="color: rgba(128, 0, 0, 1)">'</span></pre>
</div>
<h3>mode的各种模式</h3>
<table border="1" cellspacing="0">
<tbody>
<tr>
<td valign="top" width="222">
<p>模式</p>
</td>
<td valign="top" width="222">
<p>可做操作</p>
</td>
<td valign="top" width="222">
<p>若文件不存在</p>
</td>
<td valign="top" width="222">
<p>是否覆盖</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>r</p>
</td>
<td valign="top" width="222">
<p>只读</p>
</td>
<td valign="top" width="222">
<p>error</p>
</td>
<td valign="top" width="222">
<p>-</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>r+</p>
</td>
<td valign="top" width="222">
<p>读写</p>
</td>
<td valign="top" width="222">
<p>error</p>
</td>
<td valign="top" width="222">
<p>T</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>w</p>
</td>
<td valign="top" width="222">
<p>只写</p>
</td>
<td valign="top" width="222">
<p>create</p>
</td>
<td valign="top" width="222">
<p>T</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>w+</p>
</td>
<td valign="top" width="222">
<p>读写</p>
</td>
<td valign="top" width="222">
<p>create</p>
</td>
<td valign="top" width="222">
<p>T</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>a</p>
</td>
<td valign="top" width="222">
<p>只写</p>
</td>
<td valign="top" width="222">
<p>create</p>
</td>
<td valign="top" width="222">
<p>F,尾部追加写</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>a+</p>
</td>
<td valign="top" width="222">
<p>读写</p>
</td>
<td valign="top" width="222">
<p>create</p>
</td>
<td valign="top" width="222">
<p>F,尾部追加写</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>wb</p>
</td>
<td valign="top" width="222">
<p>只写二进制字符串,写入bytes</p>
</td>
<td valign="top" width="222">
<p>create</p>
</td>
<td valign="top" width="222">
<p>T</p>
</td>
</tr>
<tr>
<td valign="top" width="222">
<p>rb</p>
</td>
<td valign="top" width="222">
<p>只读二进制字符串,返回bytes</p>
</td>
<td valign="top" width="222">
<p>error</p>
</td>
<td valign="top" width="222">
<p>-</p>
</td>
</tr>
</tbody>
</table>
<p> </p>
<h2>读文件</h2>
<p>如果文件打开成功,接下来,调用 <span class="cnblogs_code">read()</span> 方法可以一次读取文件的全部内容,Python把内容读到内存<span style="color: rgba(210, 44, 74, 1)">,用一个str对象表示</span>:</p>
<div class="cnblogs_code">
<pre>>>> f.read()
'Hello, world!'</pre>
</div>
<p>最后一步是调用 <span class="cnblogs_code">close()</span> 方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:</p>
<div class="cnblogs_code">
<pre>>>> f.close()</pre>
</div>
<p><strong>关于read()、readline()、readlines()的区别可看这篇博文:</strong></p>
<p>https://www.cnblogs.com/poloyy/p/12350736.html</p>
<p> </p>
<h2>关闭文件</h2>
<p><span style="color: rgba(210, 44, 74, 1)">由于文件读写时都有可能产生</span> <span class="cnblogs_code">IOError</span> ,一旦出错,后面的 <span class="cnblogs_code">f.close()</span> 就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用 <span class="cnblogs_code"><span style="color: rgba(0, 0, 255, 1)">try</span> ... <span style="color: rgba(0, 0, 255, 1)">finally</span></span> 来实现:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
f </span>= open(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/path/to/file</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(f.read())
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> f:
f.close()</span></pre>
</div>
<p>但因为每次这样写太繁琐了,所以Python引入了 <span class="cnblogs_code">with open()</span> 来自动调用close()方法,无论是否出错</p>
<p> </p>
<h3><span class="cnblogs_code">open()</span> 与 <span class="cnblogs_code">with open()</span> 区别</h3>
<p>1、open需要主动调用close(),with不需要</p>
<p>2、open读取文件时发生异常,没有任何处理,with有很好的处理上下文产生的异常</p>
<p> </p>
<h3>用with同时操作多个文件</h3>
<div class="cnblogs_code">
<pre>with open(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test/test.py</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span>) as f1, open(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test/test2.py</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) as f2:
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(f1.read())
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(f2.read())</pre>
</div>
<p> </p>
<h2>写文件</h2>
<p>写文件和读文件是一样的,唯一区别是调用 <span class="cnblogs_code">open()</span> 函数时,需要将 <span class="cnblogs_code">mode</span> 参数改成可写的模式,如上面的表格所示</p>
<div class="cnblogs_code">
<pre>f = open(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test/test.py</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a+</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
f.write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
f.writelines(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">polo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(f.read())
f.close()</span></pre>
</div>
<p>你可以反复调用 <span class="cnblogs_code">write()</span> 来写入文件,但是务必要调用 <span class="cnblogs_code">f.close()</span> 来关闭文件。</p>
<p> </p>
<h3><span style="color: rgba(210, 44, 74, 1)">写文件的原理</span></h3>
<p>当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到<span style="color: rgba(210, 44, 74, 1)">内存缓存起来</span>,空闲的时候再慢慢写入。</p>
<p>只有调用 <span class="cnblogs_code">close()</span> 方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用<code>close()</code>的后果是数据可能只写了一部分到磁盘,剩下的丢失了。</p>
<p><strong><span style="color: rgba(210, 44, 74, 1)">所以,还是用with语句好鸭!</span></strong></p>
<div class="cnblogs_code">
<pre>with open(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test/test.py</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a+</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) as f:
f.write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</pre>
</div>
<p> </p>
<h2>关于字符编码</h2>
<p><span style="color: rgba(210, 44, 74, 1)">要写入特定编码的文本文件,请给 <span class="cnblogs_code">open()</span> 函数传入 <span class="cnblogs_code">encoding</span> 参数,将字符串自动转换成指定编码,默认 <span class="cnblogs_code">encoding=None</span> </span></p>
<p>例如,读取utf-8编码的文件:</p>
<div class="cnblogs_code">
<pre>f = open(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">test/utf8.txt</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span>, encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(f.read())</pre>
</div>
<p> </p>
<p>遇到有些编码不规范的文件,你可能会遇到 <span class="cnblogs_code">UnicodeDecodeError</span> ,因为在文本文件中可能夹杂了一些非法编码的字符。</p>
<p>遇到这种情况, <span class="cnblogs_code">open()</span> 函数还接收一个 <span class="cnblogs_code">errors</span> 参数,默认是 <span class="cnblogs_code">errors=None</span> 表示如果遇到编码错误后如何处理。最简单的方式是直接忽略</p>
<div class="cnblogs_code">
<pre>f = open(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">test/utf8.txt</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span>, encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span>, errors=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ignore</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> </p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)">划重点!!!墙裂建议使用with open()</span></strong></span></p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)"><strong>划重点!!!墙裂建议使用with open()</strong></span></strong></span></p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)"><strong><strong><strong>划重点!!!墙裂建议使用with open()</strong></strong></strong></span></strong></span></p>
<p> </p>
<p> </p>
<h1>os.open()</h1>
<h3>格式</h3>
<p><span class="cnblogs_code">os.open(file, flags[, mode])</span> </p>
<p> </p>
<h3>参数</h3>
<ul>
<li><strong>file:</strong>要打开的文件</li>
<li><strong>flags</strong>:该参数可以是以下选项,多个使用 <span class="cnblogs_code"> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">|</span><span style="color: rgba(128, 0, 0, 1)">"</span> </span> 隔开,只列常用的:
<ul>
<li><strong>os.O_RDONLY:</strong> 以只读的方式打开</li>
<li><strong>os.O_WRONLY:</strong> 以只写的方式打开</li>
<li><strong>os.O_RDWR :</strong> 以读写的方式打开</li>
<li><strong>os.O_APPEND:</strong> 以追加的方式打开</li>
<li><strong>os.O_CREAT:</strong> 创建并打开一个新文件 </li>
</ul>
</li>
</ul>
<p> </p>
<h3>简单实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding: UTF-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os, sys
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 打开文件</span>
fd = os.open( <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">foo.txt</span><span style="color: rgba(128, 0, 0, 1)">"</span>, os.O_RDWR|<span style="color: rgba(0, 0, 0, 1)">os.O_CREAT )
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 写入字符串</span>
os.write(fd, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">This is test</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关闭文件</span>
<span style="color: rgba(0, 0, 0, 1)">os.close( fd )</span></pre>
</div>
<p> </p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)">划重点!!!不建议使用os.open,还是用with open()</span></strong></span></p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)"><strong>划重点!!!不建议使用os.open,还是用with open()</strong></span></strong></span></p>
<p><span style="font-size: 14pt"><strong><span style="color: rgba(210, 44, 74, 1)"><strong><strong><strong>划重点!!!不建议使用os.open,还是用with open()</strong></strong></strong></span></strong></span></p><br><br>
来源:https://www.cnblogs.com/poloyy/p/12350158.html
頁:
[1]