Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1762138
  • 博文数量: 335
  • 博客积分: 4690
  • 博客等级: 上校
  • 技术积分: 4341
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-08 21:38
个人简介

无聊之人--除了技术,还是技术,你懂得

文章分类

全部博文(335)

文章存档

2016年(29)

2015年(18)

2014年(7)

2013年(86)

2012年(90)

2011年(105)

分类: Python/Ruby

2011-08-10 22:42:02

6.2. Working with File Objects

操作文件对象

Python has a built-in function, open, for opening a file on disk. open returns a file object, which has methods and attributes for getting information about and manipulating the opened file.

Python包含一个内置函数,open,它可以打开磁盘上面的一个文件,返回一个文件对象,该对象包含了所用来获取以及操纵打开文件的属性和方法。

Example 6.3. Opening a File

6.3 打开文件

  1. >>> f = open("/music/_singles/kairo.mp3", "rb")
  2. >>> f
  3. <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
  4. >>> f.mode
  5. 'rb'
  6. >>> f.name
  7. '/music/_singles/kairo.mp3'

1

The open method can take up to three parameters: a filename, a mode, and a buffering parameter. Only the first one, the filename, is required; the other two are optional. If not specified, the file is opened for reading in text mode. Here you are opening the file for reading in binary mode. (print open.__doc__ displays a great explanation of all the possible modes.)

Open方法可以接受三个参数,文件名字,文件的读写模式,以及一个缓冲参数。只有第一个文件名字是必须的,其它的两个都是可选的。如果你不说明,文件以文本模式进行读。这儿你是以二进制的方式进行读文件.(打印open._doc_显示了所有模式的详细说明。)

2

The open function returns an object (by now, this should not surprise you). A file object has several useful attributes.

Open函数返回了一个对象(现在你不应该感到惊讶),一个文件对象拥有好几个非常有用的属性。

3

The mode attribute of a file object tells you in which mode the file was opened.

文件对象的模式属性说明了你所打开文件的模式。

4

The name attribute of a file object tells you the name of the file that the file object has open.

文件对象的名字属性说明了文件对象所所打开的文件的名字。

6.2.1. Reading Files

6.2.1 读取文件

After you open a file, the first thing you'll want to do is read from it, as shown in the next example.

当你打开文件以后,接下来你所想的第一件事,正如下面例子所要说明的一样,就是从中读取文件的内容。

Example 6.4. Reading a File

6.4 读取文件

  1. >>> f
  2. <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
  3. >>> f.tell()
  4. 0
  5. >>> f.seek(-128, 2)
  6. >>> f.tell()
  7. 7542909
  8. >>> tagData = f.read(128)
  9. >>> tagData
  10. 'TAGKAIRO****THE BEST GOA ***DJ MARY-JANE***
  11. Rave Mix 2000 \037'
  12. >>> f.tell()
  13. 7543037

1

A file object maintains state about the file it has open. The tell method of a file object tells you your current position in the open file. Since you haven't done anything with this file yet, the current position is 0, which is the beginning of the file.

文件对象保持了它所打开的文件的状态信息。文件对象的Tell方法告诉你你所打开文件的文件指针的当前位置。因为你对该文件没有进行任何操作,文件指针的当前位置为0,也就是文件的开始处。

2

The seek method of a file object moves to another position in the open file. The second parameter specifies what the first one means; 0 means move to an absolute position (counting from the start of the file), 1 means move to a relative position (counting from the current position), and 2 means move to a position relative to the end of the file. Since the MP3 tags you're looking for are stored at the end of the file, you use 2 and tell the file object to move to a position 128 bytes from the end of the file.

文件对象的seek方法用来将文件指针移动到文件对象所打开的文件的另一个位置。第二个参数说明了第一个参数的意思:0意味着移动到一个绝对位置(依赖于文件的起始位置)。1意味着将文件指针移动到一个相对位置(依赖与当前位置),而2 意味着将文件指针移动到距离文件结束处的相对位置。因为你打算寻找的MP3标签储存在文件的尾部,你选择2,然后告诉文件对象将文件指针移动到距离文件结束处128个字节处。

3

The tell method confirms that the current file position has moved.

Tell方法来确定移动文件后,文件指针的当前位置。

4

The read method reads a specified number of bytes from the open file and returns a string with the data that was read. The optional parameter specifies the maximum number of bytes to read. If no parameter is specified, read will read until the end of the file. (You could have simply said read() here, since you know exactly where you are in the file and you are, in fact, reading the last 128 bytes.) The read data is assigned to the tagData variable, and the current position is updated based on how many bytes were read.

Read函数从打开的文件中读取一定的字节数,然后返回读取的字符串。可选的参数说明了所能读取的最大字节数。如果没有参数说明,read函数将读取到文件结束(你可能会简单的调用read(),这是因为你知道文件指针在文件的位置并且你知道你正在读取最后128个字节)。函数读取的数据被赋值给变量tagData。当前文件指针的位置被更新,具体的值由你所读取的字节数决定。

5

The tell method confirms that the current position has moved. If you do the math, you'll see that after reading 128 bytes, the position has been incremented by 128.

Tell再一次确定了文件指针移动后的位置。如果你计算一下,你就会发现在读取了128个字节后,位置的计数增加了128.

6.2.2. Closing Files

6.2.2 关闭文件

Open files consume system resources, and depending on the file mode, other programs may not be able to access them. It's important to close files as soon as you're finished with them.

打开文件是消耗系统资源,它依赖于文件的打开模式,其它的程序将不能访问这些资源。一旦你完成了对文件的操作,你就应该尽可能快的关闭文件

Example 6.5. Closing a File

6.5 关闭文件

  1. >>> f
  2. <open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
  3. >>> f.closed
  4. False
  5. >>> f.close()
  6. >>> f
  7. <closed file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
  8. >>> f.closed
  9. True
  10. >>> f.seek(0)
  11. Traceback (innermost last):
  12.   File "", line 1, in ?
  13. ValueError: I/O operation on closed file
  14. >>> f.tell()
  15. Traceback (innermost last):
  16.   File "", line 1, in ?
  17. ValueError: I/O operation on closed file
  18. >>> f.read()
  19. Traceback (innermost last):
  20.   File "", line 1, in ?
  21. ValueError: I/O operation on closed file
  22. >>> f.close()

1

The closed attribute of a file object indicates whether the object has a file open or not. In this case, the file is still open (closed is False).

一个文件对象的关闭属性表明了一个文件对象是打开还是关闭。在本例中,文件没有关闭(close就为假)。

2

To close a file, call the close method of the file object. This frees the lock (if any) that you were holding on the file, flushes buffered writes (if any) that the system hadn't gotten around to actually writing yet, and releases the system resources.

为了关闭一个文件,应该调用文件的对象的close方法。这样就释放了文件上面的你所占有的锁(如果有的话),然后刷洗系统还没有来得及写到磁盘上的缓冲,然后释放系统的资源。

3

The closed attribute confirms that the file is closed.

Closed属性确定文件是关闭的。

4

Just because a file is closed doesn't mean that the file object ceases to exist. The variable f will continue to exist until it goes out of scope or gets manually deleted. However, none of the methods that manipulate an open file will work once the file has been closed; they all raise an exception.

仅仅关闭一个文件并不意味着指向该文件的文件对象也销毁。变量f,除非退出它的作用域或是手工删除,否则f将持续存在。然而一旦文件被关闭,没有任何方法再来对打开的文件进行任何操作。如果操作,将会抛出异常。

5

Calling close on a file object whose file is already closed does not raise an exception; it fails silently.

在一个已经关闭的文件上面调用close不会抛出异常。它会失败,但是没有任何反应。

6.2.3. Handling I/O Errors

6.2.3 处理I/O错误

Now you've seen enough to understand the file handling code in the fileinfo.py sample code from the previous chapter. This example shows how to safely open and read from a file and gracefully handle errors.

现在你已经足够能看懂先前例子fileInfo.py中的文件处理代码。这个例子展示了如何安全的打开然后读取一个文件,最后优雅的处理错误

Example 6.6. File Objects in MP3FileInfo

6.6 MP3FileInfo中的文件对象

      

  1. try:
  2.             fsock = open(filename, "rb", 0)
  3.             try:
  4.                 fsock.seek(-128, 2)
  5.                 tagdata = fsock.read(128)
  6.             finally:
  7.                 fsock.close()
  8.             .
  9.             .
  10.             .
  11.         except IOError:
  12.             pass

1

Because opening and reading files is risky and may raise an exception, all of this code is wrapped in a try...except block. (Hey, isn't standardized indentation great? This is where you start to appreciate it.)

因为打开和读取一个文件是有风险的,同时可能抛出很多异常,因此所有的代码都被封装在一个try….except代码块中(嘿,这是不是标准的缩进?这儿你就开始欣赏它了)

2

The open function may raise an IOError. (Maybe the file doesn't exist.)

Open函数可能抛出IOErro(或许文件根本就不存在)

3

The seek method may raise an IOError. (Maybe the file is smaller than 128 bytes.)

Seek方法可能会抛出IOError异常(文件的大小可能小于128字节数)。

4

The read method may raise an IOError. (Maybe the disk has a bad sector, or it's on a network drive and the network just went down.)

Read函数可能会抛出IOError异常(比如磁盘上面有坏的扇区,或是文件在网络驱动器上面然后网络宕机)。

5

This is new: a try...finally block. Once the file has been opened successfully by the open function, you want to make absolutely sure that you close it, even if an exception is raised by the seek or read methods. That's what a try...finally block is for: code in the finally block will always be executed, even if something in the tryblock raises an exception. Think of it as code that gets executed on the way out, regardless of what happened before.

这是一个新的try….finally代码块。通过调用Open函数,一旦文件被成功的打开,你想百分百的确定文件已经关闭,即使抛出了一个异常,如右seek或是由read方法引起的。这就是try…finally代码块中的代码在finally中的代码无论如何都被执行,即使try代码块中抛出异常。你可以认为不论前面发生了什么,这段代码最终都会被执行。

6

At last, you handle your IOError exception. This could be the IOError exception raised by the call to open, seek, or read. Here, you really don't care, because all you're going to do is ignore it silently and continue. (Remember, pass is a Python statement that does nothing.) That's perfectly legal; “handling” an exception can mean explicitly doing nothing. It still counts as handled, and processing will continue normally on the next line of code after the try...except block.

最后,你捕捉 IOError 异常。IOError异常可能由调用函数open,seek,read引起。这儿你不必关心,这是因为你所做的就是完全忽略这些错误然后继续(记住,忽略是一个Python语句,它什么也不做)。这是完全合法的:处理一个异常可以是显式什么也不做。它仍然是处理的一种方式,程序将会正常进行,在try…except代码块后的代码将会按顺序执行。

6.2.4. Writing to Files

6.2.4 写文件

As you would expect, you can also write to files in much the same way that you read from them. There are two basic file modes:

  • "Append" mode will add data to the end of the file.
  • "write" mode will overwrite the file.

Either mode will create the file automatically if it doesn't already exist, so there's never a need for any sort of fiddly "if the log file doesn't exist yet, create a new empty file just so you can open it for the first time" logic. Just open it and start writing.

正如你所期望的那样,你可以使用的方式来写你所读取的文件。写文件有两种模式:

         追加模式将文件的内容追加到文件的结尾;

         重写模式将覆盖掉原来的原件

Example 6.7. Writing to Files

6.7 写文件

  1. >>> logfile = open('test.log', 'w')
  2. >>> logfile.write('test succeeded')
  3. >>> logfile.close()
  4. >>> print file('test.log').read()
  5. test succeeded
  6. >>> logfile = open('test.log', 'a')
  7. >>> logfile.write('line 2')
  8. >>> logfile.close()
  9. >>> print file('test.log').read()
  10. test succeededline 2

1

You start boldly by creating either the new file test.log or overwrites the existing file, and opening the file for writing. (The second parameter "w" means open the file for writing.) Yes, that's all as dangerous as it sounds. I hope you didn't care about the previous contents of that file, because it's gone now.

你可以大胆的开始,或是创建一个新文件,test.log,或是重写掉已经存在的文件。然后打开该文件,好等待写入。(第二个参数“w”,的意思是以写的方式打开文件。对的,这听起来很危险。我希望你不是太关注先前文件的内容,因为事情已经发生。

2

You can add data to the newly opened file with the write method of the file object returned by open.

你可以向新打开的文件追加数据,可以使用open对象返回的文件对象的write方法来实现。

3

file is a synonym for open. This one-liner opens the file, reads its contents, and prints them.

Fileopen的同义词。这行打开了文件,然后读取其内容,最后打印。

4

You happen to know that test.log exists (since you just finished writing to it), so you can open it and append to it. (The "a" parameter means open the file for appending.) Actually you could do this even if the file didn't exist, because opening the file for appending will create the file if necessary. But appending will neverharm the existing contents of the file.

你刚好知道test.log是存在的(既然你刚刚完成对该文件的写入),因此你可以打开,然后想起追加内容。(‘a’参数的意思是以追加的方式打开文件)实际上即使文件不存在你仍然也可以这么做,这是因为如果有必要,写模式将会创建一个新文件用来写。但是追加方式绝不会对文件原来的内容有任何损坏。

5

As you can see, both the original line you wrote and the second line you appended are now in test.log. Also note that carriage returns are not included. Since you didn't write them explicitly to the file either time, the file doesn't include them. You can write a carriage return with the "\n" character. Since you didn't do this, everything you wrote to the file ended up smooshed together on the same line.

正如你所看到的,不论是你刚开始写入的第一行内容,还是你追加的第二行内容都已经写到文件test.log中了。同样值得注意的是,回车键并没有被包含在里面。你可以用“\n”来写入回车。因为刚才你没有这么做,你所写入文件的所有内容都在同一行。

 

阅读(942) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~