Python 文件 IO

Python 文件 IO

Python 文件 IO Python3 实例

以下代码演示了Python基本的文件操作,包括 open,read,write:


# Filename : test.py
  
# 写文件 with open("test.txt", "wt") as out_file:
     out_file.write("该文本会写入到文件中n看到我了吧!")  
# Read a file with open("test.txt", "rt") as in_file:
     text = in_file.read() 
print(text) 

执行以上代码输出结果为:

 该文本会写入到文件中 看到我了吧! 

Python 文件 IO Python3 实例

第十一回、PHP基础教程,PHP文件上传问题补充

单文件上传

PHP上传文件非常简单,你需要一个上传的HTML文件(<FORM>),一个保存文件的PHP文件(保存),一个查询上传文件清单的工具。

真正实现完整功能的上传和管理需要使用数据库,我的网站俱乐部里面上传文件一开放很快就传了几万个文件。

最简单的方法不用数据库,可以用一个PHP文件实现,这个文件列出指定目录下的所有文件,然后提供一个上传的FORM,最后检测是否提交了FORM数据,是就保存文件到指定位置。

PHP手册第39章有关于处理这些问题的说明,我复制粘贴如下:

本特性可以使用户上传文本和二进制文件。用 PHP 的认证和文件操作函数,可以完全控制允许哪些人上传以及文件上传后怎样处理。

PHP 能够接受任何来自符合 RFC-1867 标准的浏览器(包括 Netscape Navigator 3 及更高版本,打了补丁的 Microsoft Internet Explorer 3 或者更高版本)上传的文件。

相关的设置: 请参阅 php.ini 的 file_uploads,upload_max_filesize,upload_tmp_dirpost_max_size 以及 max_input_time 设置选项。

请注意 PHP 也支持 PUT 方法的文件上传,Netscape Composer 和 W3C 的 Amaya 客户端使用这种方法。请参阅对 PUT 方法的支持以获取更多信息。

例 39.1. 文件上传表单

可以如下建立一个特殊的表单来支持文件上传:

<!– The data encoding type, enctype, MUST be specified as below –>

<
form enctype=”multipart/form-data” action=”__URL__” method=”POST”>

<!– MAX_FILE_SIZE must precede the file input field –>

<input type=”hidden” name=”MAX_FILE_SIZE” value=”30000″ />

<!– Name of input element determines name in $_FILES array –>

Send this file: <input name=”userfile” type=”file” />

<input type=”submit” value=”Send File” />

</form>

以上范例中的 __URL__ 应该被换掉,指向一个真实的 PHP 文件。

MAX_FILE_SIZE 隐藏字段(单位为字节)必须放在文件输入字段之前,其值为接收文件的最大尺寸。这是对浏览器的一个建议,PHP 也会检查此项。在浏览器端可以简单绕过此设置,因此不要指望用此特性来阻挡大文件。实际上,PHP 设置中的上传文件最大值是不会失效的。但是最好还是在表单中加上此项目,因为它可以避免用户在花时间等待上传大文件之后才发现文件过大上传失败的麻烦。

注意: 要确保文件上传表单的属性是 enctype=”multipart/form-data”,否则文件上传不了。

全局变量 $_FILES 自 PHP 4.1.0 起存在(在更早的版本中用 $HTTP_POST_FILES 替代)。此数组包含有所有上传的文件信息。

以上范例中 $_FILES 数组的内容如下所示。我们假设文件上传字段的名称如上例所示,为 userfile。名称可随意命名。

$_FILES[‘userfile’][‘name’]

客户端机器文件的原名称。

$_FILES[‘userfile’][‘type’]

文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是“image/gif”。不过此 MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。

$_FILES[‘userfile’][‘size’]

已上传文件的大小,单位为字节。

$_FILES[‘userfile’][‘tmp_name’]

文件被上传后在服务端储存的临时文件名。

$_FILES[‘userfile’][‘error’]

和该文件上传相关的错误代码。此项目是在 PHP 4.2.0 版本中增加的。

文件被上传后,默认地会被储存到服务端的默认临时目录中,除非 php.ini 中的 upload_tmp_dir 设置为其它的路径。服务端的默认临时目录可以通过更改 PHP 运行环境的环境变量 TMPDIR 来重新设置,但是在 PHP 脚本内部通过运行 putenv() 函数来设置是不起作用的。该环境变量也可以用来确认其它的操作也是在上传的文件上进行的。

例 39.2. 使文件上传生效

请查阅函数 is_uploaded_file() 和 move_uploaded_file() 以获取进一步的信息。以下范例处理由表单提供的文件上传。

<?php

// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead

// of $_FILES.

$uploaddir = ‘/var/www/uploads/’;

$uploadfile = $uploaddir . basename($_FILES[‘userfile’][‘name’]);

echo ‘<pre>’;

if (move_uploaded_file($_FILES[‘userfile’][‘tmp_name’], $uploadfile))
{

echo “File is valid, and was successfully uploaded.n”;

} else{

echo “Possible file upload attack!n”;

}

echo ‘Here is some more debugging info:’;

print_r($_FILES);

print “</pre>”;

?>

接受上传文件的 PHP 脚本为了决定接下来要对该文件进行哪些操作,应该实现任何逻辑上必要的检查。例如可以用 $_FILES[‘userfile’][‘size’] 变量来排除过大或过小的文件,也可以通过 $_FILES[‘userfile’][‘type’] 变量来排除文件类型和某种标准不相符合的文件,但只把这个当作一系列检查中的第一步,因为此值完全由客户端控制而在 PHP 端并不检查。自 PHP 4.2.0 起,还可以通过 $_FILES[‘userfile’][‘error’] 变量来根据不同的错误代码来计划下一步如何处理。不管怎样,要么将该文件从临时目录中删除,要么将其移动到其它的地方。

如果表单中没有选择上传的文件,则 PHP 变量 $_FILES[‘userfile’][‘size’] 的值将为 0,$_FILES[‘userfile’][‘tmp_name’] 将为空。

如果该文件没有被移动到其它地方也没有被改名,则该文件将在表单请求结束时被删除。

例 39.3. 上传一组文件

PHP 的 HTML 数组特性甚至支持文件类型。

<
form action=”” method=”post” enctype=”multipart/form-data”>

<p>Pictures:

<input type=”file” name=”pictures[]” />

<input type=”file” name=”pictures[]” />

<input type=”file” name=”pictures[]” />

<input type=”submit” value=”Send” />

</p>

</form>

<?php

foreach ($_FILES[“pictures”][“error”] as $key =>$error)
{

if ($error == UPLOAD_ERR_OK)
{

$tmp_name = $_FILES[“pictures”][“tmp_name”][$key];

$name = $_FILES[“pictures”][“name”][$key];

move_uploaded_file($tmp_name, “data/$name”);

}

}

?>

6.2 PHP实现多文件上传

一、配置文件:config.ini

DefFileType=jpg,jpeg,gif,png,bmp,swf

DefFileSize=100

配置文件说明:

DefFileType:可以上传的文件类型为文件上传是检测文件类型之用

DefFileSize:对上传文件的大小的控制,默认100k你可以任意更改

二、上传代码:

<?php

$opt=$_REQUEST[‘opt’];

if($opt==”upload”)

{

$AllFile=$_FILES[‘allfile’];

$FilePath=$_REQUEST[‘FilePath’];

$FileCount=$_REQUEST[‘CountFile’];

$SetFileName=$_REQUEST[‘SetFileName’];

//读取文件类型限制和文件大小限制config.ini

$Config=file(“config.ini”);

$DefaultType=split(“=”,$Config[0]);

$DefaultSize=split(“=”,$Config[1]);

$$DefaultType[0]=split(“,”,strtolower($DefaultType[1]));

$$DefaultSize[0]=$DefaultSize[1]*1024;

$DefTypeCount=count($DefFileType);

//检测目录是否存在

if(!@file_exists($FilePath))

{

@mkdir($FilePath,”777″);

}

$Succ=0;

$Fail=0;

$FailReason=””;

for($i=0;

$i<$FileCount;

$i++)

{

$tmpName[$i]=$AllFile[‘tmp_name’][$i];

$Name[$i]=$AllFile[‘name’][$i];

$FileSize[$i]=$AllFile[‘size’][$i];

$ClassName[$i]=strtolower(substr($Name[$i],strrpos($Name[$i],”.”)+1,strlen($Name[$i])));

if($SetFileName)

$FileName[$i]=date(“YmdHis”).rand(1000000,9999999).$i.”.”.$ClassName[$i];

else

$FileName[$i]=$Name[$i];

for($j=0;

$j<$DefTypeCount;

$j++)

{

if(trim($ClassName[$i])==trim($DefFileType[$j]))

{

$AllType[$i]=1;

break;

}

else

{

$AllType[$i]=0;

}

}

if(!$AllType[$i])

{

$Fail++;

$FailReason.=$Fail.”、文件””.$Name[$i].””上传的失败原因:文件类型不匹配<br>”;

unset($AllType);

continue;

}

elseif($FileSize[$i]>$DefFileSize)

{

$Fail++;

$FailReason.=$Fail.”、文件””.$Name[$i].””上传的失败原因:文件太大<br>”;

continue;

}

elseif(@copy($tmpName[$i],$FilePath.”/”.$FileName[$i]))

{

$Succ++;

}

else

{

$Fail++;

$FailReason.=$Fail.”、文件””.$Name[$i].””上传的失败原因:未知错误<br>”;

}

}

echo $Succ.”个文件上传成功!”.$Fail.”文件上传失败!<a href=’index.php’>返回</a>
<br>”.$FailReason;

exit;

}

?>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head>

<meta http-equiv=”Content-Type” content=”text/html;

charset=gb2312″ />

<title>无标题文档</title>

<style type=”text/css”>

.fonttitle{font-family:”宋体”;

font-size:12px;

font-weight:bold;

line-height:25px;

}

.fontall{font-family:”宋体”;

font-size:12px;

line-height:25px;

}

.inputset{ border:0;

border-bottom:1px solid
#000;

text-align:center;

}

</style>

<script language=”JavaScript”>

<!–

var rowIndex=0;

function addLine(obj1,num)

{

if(document.form1.FileNum.value>100 || document.form1.FileNum.value<1)

{

alert(“您最多同时上传100个文件,最少上传1个文件!”);

if(document.form1.FileNum.value>100)

{

document.form1.FileNum.value=100;

}

else

{

if(document.form1.FileNum.value<1)

{

document.form1.FileNum.value=1;

}

}

addLine(document.form2.CountFile,document.form1.FileNum.value);

}

else

{

document.form2.style.display=””;

obj1.value=num;

document.form2.FilePath.value=document.form1.FilePath.value;

if(document.form1.SetFileName1.checked)

{

document.form2.SetFileName.value=”0″;

}

else

{

document.form2.SetFileName.value=”1″;

}

var objSourceRow=obj1.parentNode.parentNode;

var objTable=obj1.parentNode.parentNode.parentNode.parentNode;

var html1=”选择文件:”;

var html2=” <input type=’file’ name=’allfile’/>”;

var cha=rowIndex-num;

if(cha<=0)

{

for(i=rowIndex;

i<num;

i++)

{

rowIndex++;

var objRow=objTable.insertRow(rowIndex);

var objCell;

objCell=objRow.insertCell(0);

objCell.height=17;

objCell.align=”center”;

objCell.style.background=”#FFFFFF”;

objCell.className=”fontall”;

objCell.innerHTML=html1;

objCell=objRow.insertCell(1);

objCell.style.background=”#FFFFFF”;

objCell.className=”fontall”;

objCell.innerHTML=html2.replace(“allfile”,”allfile[“+(rowIndex-1)+”]”);

}

}

else

{

for(i=0;

i<cha;

i++)

{

objTable.deleteRow(rowIndex);

rowIndex–;

}

}

}

}

//–>

</script>

</head>

<body>

<table width=”529″ border=”0″ cellpadding=”0″ cellspacing=”1″ bgcolor=”#000000″>

<tr>

<td width=”527″ height=”13″ bgcolor=”#FFFFFF”>PHP多文件上传程序</td>

</tr>

<tr>

<td height=”17″ bgcolor=”#FFFFFF”>
<form id=”form1″ name=”form1″ method=”post” action=”” style=”margin:0;

“>

<table width=”100%” border=”0″ cellspacing=”0″ cellpadding=”0″>

<tr>

<td>
</td>

</tr>

<tr>

<td>上传文件数:

<input name=”FileNum” type=”text” id=”FileNum” value=”1″ size=”5″ />

根;

上传路径:

<input name=”FilePath” type=”text” id=”FilePath” value=”upload” size=”20″ />

</td>

</tr>

<tr>

<td>文件名设置:

<input name=”SetFileName1″ type=”checkbox” id=”SetFileName1″ value=”0″ onclick=”SetFileName2.checked=false;

” />

保持原文件名

<input name=”SetFileName2″ type=”checkbox” id=”SetFileName2″ value=”1″ checked=”checked” onclick=”SetFileName1.checked=false;

” />

自动更改文件名</td>

</tr>

<tr>

<td>
</td>

</tr>

<tr>

<td>
<input type=”button” name=”Submit” value=” 设 置 ” onclick=”addLine(document.form2.CountFile,document.form1.FileNum.value)”/>
</td>

</tr>

<tr>

<td>
</td>

</tr>

</table>

</form>

</td>

</tr>

</table>

<
form action=”” method=”post” enctype=”multipart/form-data” name=”form2″ id=”form2″ style=”display:none;

“>

<table id=”table1″ width=”529″ border=”0″ cellpadding=”0″ cellspacing=”1″ bgcolor=”#000000″>

<tr>

<td width=”526″ height=”13″ bgcolor=”#FFFFFF” colspan=”2″>上传文件

<input name=”CountFile” type=”hidden” id=”CountFile” />

<input name=”FilePath” type=”hidden” id=”FilePath” />

<input name=”SetFileName” type=”hidden” id=”SetFileName” value=”1″ />

<input name=”opt” type=”hidden” id=”opt” value=”upload” />
</td>

</tr>

</table>

<table width=”529″ border=”0″ cellpadding=”0″ cellspacing=”0″>

<tr>

<td height=”42″>
<input type=”submit” name=”Submit2″ value=” 上 传 ” />
</td>

</tr>

</table>

</form>

</body>

</html>

python文件操作

一 介绍

计算机系统分为:计算机硬件,操作系统,应用程序三部分。
我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。
有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:

#1. 打开文件,得到文件句柄并赋值给一个变量
#2. 通过句柄对文件进行操作
#3. 关闭文件

 

二 在python中

#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

#2. 通过句柄对文件进行操作
data=f.read()

#3. 关闭文件
f.close()

 

三 f=open(‘a.txt’,’r’)的过程分析

#1、由应用程序向操作系统发起系统调用open(...)

#2、操作系统打开该文件,并返回一个文件句柄给应用程序

#3、应用程序将文件句柄赋值给变量f

 

四 强调!!!

#强调第一点:
打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
1f.close()
#回收操作系统级打开的文件
2、del f
#回收应用程序级的变量

其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源,
python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()

虽然我这么说,但是很多同学还是会很不要脸地忘记f.close(),对于这些不长脑子的同学,我们推荐傻瓜式操作方式:
使用with关键字来帮我们管理上下文
with open(‘a.txt’,‘w’) as f:
pass

with open(‘a.txt’,‘r’) as read_f,open(‘b.txt’,‘w’) as write_f:
data=read_f.read()
write_f.write(data)

强调第一点:资源回收

 

#强调第二点:
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,
那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码
去打开文件,在windows下是gbk,在linux下是utf-8。
这就用到了上节课讲的字符编码的知识:若要保证不乱码,文件以什么方式存的,
就要以什么方式打开。

f=open(‘a.txt’,‘r’,encoding=‘utf-8’)

 

五 打开文件的模式

文件句柄 = open(‘文件路径’, ‘模式’)

#1. 打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则创建;存在则清空内容】
a, 之追加写模式【不可读;不存在则创建;存在则只追加内容】

#2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作
(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、
图片文件的jgp格式、视频文件的avi格式)
rb
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,
不能指定编码

#3. 了解部分
"+" 表示可以同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
a+, 写读【可读,可写】

x, 只写模式【不可读;不存在则创建,存在则报错】
x+ ,写读【可读,可写】
xb

 

六 操作文件的方法

#掌握
f.read() #读取所有内容,光标移动到文件末尾
f.readline() #读取一行内容,光标移动到第二行首部
f.readlines() #读取每一行内容,存放于列表中

f.write(‘1111n222n’) #针对文本模式的写,需要自己写换行符
f.write(‘1111n222n’.encode(‘utf-8’)) #针对b模式的写,需要自己写换行符
f.writelines([‘333n’,‘444n’]) #文件模式
f.writelines([bytes(‘333n’,encoding=‘utf-8’),‘444n’.encode(‘utf-8’)]) #b模式

#了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #如果文件打开模式为b,则没有该属性
f.flush() #立刻将文件内容从内存刷到硬盘
f.name

 

练习,利用b模式,编写一个cp工具,要求如下:
1. 既可以拷贝文本又可以拷贝视频,图片等文件
2. 用户一旦参数错误,打印命令的正确使用方法,如usage: cp source_file target_file
提示:可以用import sys,然后用sys.argv获取脚本后面跟的参数

import sys
if len(sys.argv) != 3:
    print('usage: cp source_file target_file')
    sys.exit()

source_file,target_file=sys.argv[1],sys.argv[2]
with open(source_file,‘rb’) as read_f,open(target_file,‘wb’) as write_f:
for line in read_f:
write_f.write(line)

 

七文件内光标移动

1: read(3):
a. 文件打开方式为文本模式时,代表读取3个字符
b. 文件打开方式为b模式时,代表读取3个字节
2: tell() 返回文件的当前位置
3: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate
注意:
a. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的,常用seek(0)移动到开头,seek(0, 2)移动到最后面 。
b. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
 

八 文件的修改

文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
 

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

import os

with open(‘a.txt’) as read_f,open(‘.a.txt.swap’,‘w’) as write_f:
data=read_f.read()
#全部读入内存,如果文件很大,会很卡
data=data.replace(‘alex’,‘SB’)
#在内存中完成修改

write_f.write(data)
#一次性写入新文件

os.remove(‘a.txt’)
os.rename(‘.a.txt.swap’,‘a.txt’)

 

方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

import os

with open(‘a.txt’) as read_f,open(‘.a.txt.swap’,‘w’) as write_f:
for line in read_f:
line=line.replace(‘alex’,‘SB’)
write_f.write(line)

os.remove(‘a.txt’)
os.rename(‘.a.txt.swap’,‘a.txt’)