|
5 | 5 | ----------
|
6 | 6 | 问题
|
7 | 7 | ----------
|
8 |
| -You have an open file object in Python, but need to pass it to C extension code that will |
9 |
| -use the file. |
| 8 | +你在Python中有一个打开的文件对象,但是需要将它传给要使用这个文件的C扩展。 |
10 | 9 |
|
11 | 10 | |
|
12 | 11 |
|
13 | 12 | ----------
|
14 | 13 | 解决方案
|
15 | 14 | ----------
|
16 |
| -To convert a file to an integer file descriptor, use PyFile_FromFd(), as shown: |
| 15 | +要将一个文件转换为一个整型的文件描述符,使用 ``PyFile_FromFd()`` ,如下: |
17 | 16 |
|
18 |
| -PyObject *fobj; /* File object (already obtained somehow) */ |
19 |
| -int fd = PyObject_AsFileDescriptor(fobj); |
20 |
| -if (fd < 0) { |
21 |
| - return NULL; |
22 |
| -} |
| 17 | +:: |
23 | 18 |
|
24 |
| -The resulting file descriptor is obtained by calling the fileno() method on fobj. Thus, |
25 |
| -any object that exposes a descriptor in this manner should work (e.g., file, socket, etc.). |
26 |
| -Once you have the descriptor, it can be passed to various low-level C functions that |
27 |
| -expect to work with files. |
28 |
| -If you need to convert an integer file descriptor back into a Python object, use |
29 |
| -PyFile_FromFd() as follows: |
| 19 | + PyObject *fobj; /* File object (already obtained somehow) */ |
| 20 | + int fd = PyObject_AsFileDescriptor(fobj); |
| 21 | + if (fd < 0) { |
| 22 | + return NULL; |
| 23 | + } |
30 | 24 |
|
31 |
| -int fd; /* Existing file descriptor (already open) */ |
32 |
| -PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1); |
| 25 | +结果文件描述符是通过调用 ``fobj`` 中的 ``fileno()`` 方法获得的。 |
| 26 | +因此,任何以这种方式暴露给一个描述器的对象都适用(比如文件、套接字等)。 |
| 27 | +一旦你有了这个描述器,它就能被传递给多个低级的可处理文件的C函数。 |
33 | 28 |
|
34 |
| -The arguments to PyFile_FromFd() mirror those of the built-in open() function. NULL |
35 |
| -values simply indicate that the default settings for the encoding, errors, and newline |
36 |
| -arguments are being used. |
| 29 | +如果你需要转换一个整型文件描述符为一个Python对象,适用下面的 ``PyFile_FromFd()`` : |
| 30 | + |
| 31 | +:: |
| 32 | + |
| 33 | + int fd; /* Existing file descriptor (already open) */ |
| 34 | + PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1); |
| 35 | + |
| 36 | +``PyFile_FromFd()`` 的参数对应内置的 ``open()`` 函数。 |
| 37 | +NULL表示编码、错误和换行参数使用默认值。 |
37 | 38 |
|
38 | 39 | |
|
39 | 40 |
|
40 | 41 | ----------
|
41 | 42 | 讨论
|
42 | 43 | ----------
|
43 |
| -If you are passing file objects from Python to C, there are a few tricky issues to be |
44 |
| -concerned about. First, Python performs its own I/O buffering through the io module. |
45 |
| -Prior to passing any kind of file descriptor to C, you should first flush the I/O buffers |
46 |
| -on the associated file objects. Otherwise, you could get data appearing out of order on |
47 |
| -the file stream. |
48 |
| -Second, you need to pay careful attention to file ownership and the responsibility of |
49 |
| -closing the file in particular. If a file descriptor is passed to C, but still used in Python, |
50 |
| -you need to make sure C doesn’t accidentally close the file. Likewise, if a file descriptor |
51 |
| -is being turned into a Python file object, you need to be clear about who is responsible |
52 |
| -for closing it. The last argument to PyFile_FromFd() is set to 1 to indicate that Python |
53 |
| -should close the file. |
54 |
| -If you need to make a different kind of file object such as a FILE * object from the C |
55 |
| -standard I/O library using a function such as fdopen(), you’ll need to be especially |
56 |
| -careful. Doing so would introduce two completely different I/O buffering layers into |
57 |
| -the I/O stack (one from Python’s io module and one from C stdio). Operations such |
58 |
| -as fclose() in C could also inadvertently close the file for further use in Python. If given |
59 |
| -a choice, you should probably make extension code work with the low-level integer file |
60 |
| -descriptors as opposed to using a higher-level abstraction such as that provided by |
61 |
| -<stdio.h>. |
| 44 | +如果将Python中的文件对象传给C,有一些注意事项。 |
| 45 | +首先,Python通过 ``io`` 模块执行自己的I/O缓冲。 |
| 46 | +在传递任何类型的文件描述符给C之前,你都要首先在相应文件对象上刷新I/O缓冲。 |
| 47 | +不然的话,你会打乱文件系统上面的数据。 |
| 48 | + |
| 49 | +其次,你需要特别注意文件的归属者以及关闭文件的职责。 |
| 50 | +如果一个文件描述符被传给C,但是在Python中还在被使用着,你需要确保C没有意外的关闭它。 |
| 51 | +类似的,如果一个文件描述符被转换为一个Python文件对象,你需要清楚谁应该去关闭它。 |
| 52 | +``PyFile_FromFd()`` 的最后一个参数被设置成1,用来指出Python应该关闭这个文件。 |
| 53 | + |
| 54 | +如果你需要从C标准I/O库中使用如 ``fdopen()`` 函数来创建不同类型的文件对象比如 ``FILE *`` 对象, |
| 55 | +你需要特别小心了。这样做会在I/O堆栈中产生两个完全不同的I/O缓冲层 |
| 56 | +(一个是来自Python的 ``io`` 模块,另一个来自C的 ``stdio`` )。 |
| 57 | +像C中的 ``fclose()`` 会关闭Python要使用的文件。 |
| 58 | +如果让你选的话,你应该会选择去构建一个扩展代码来处理底层的整型文件描述符, |
| 59 | +而不是使用来自<stdio.h>的高层抽象功能。 |
0 commit comments