将文件描述符包装成文件对象

问题

你有一个对应于操作系统上一个已打开的 I/O 通道 (比如文件、管道、套接字等)的整型文件描述符,你想将它包装成一个更高层的 Python 文件对象。

解法

一个文件描述符和一个打开的普通文件是不一样的。文件描述符仅仅是一个由操作系统指定的整数,用来指代某个系统的 I/O 通道。如果你碰巧有这么一个文件描述符,你可以通过使用 open() 函数来将其包装为一个 Python 的文件对象。你仅仅只需要使用这个整数值的文件描述符作为第一个参数来代替文件名即可。例如:

# Open a low-level file descriptor
import os
fd = os.open('somefile.txt', os.O_WRONLY j os.O_CREAT)# Turn into a proper file
f = open(fd, 'wt')
f.write('hello world\n')
f.close()

当高层的文件对象被关闭或者破坏的时候,底层的文件描述符也会被关闭。如果这个并不是你想要的结果,你可以给 open() 函数传递一个可选的 colsefd=False 。比如:

# Create a file object, but don't close underlying fd when done
f = open(fd, 'wt', closefd=False)
...

讨论

在 Unix 系统中,这种包装文件描述符的技术可以很方便的将一个类文件接口作用于一个以不同方式打开的 I/O 通道上,如管道、套接字等。举例来讲,下面是一个操作管道的例子:

from socket import socket, AF_INET, SOCK_STREAMdef echo_client(client_sock, addr):print('Got connection from', addr)# Make text-mode file wrappers for socket reading/writingclient_in = open(client_sock.fileno(), 'rt', encoding='latin-1',closefd=False)client_out = open(client_sock.fileno(), 'wt', encoding='latin-1',closefd=False)# Echo lines back to the client using file I/Ofor line in client_in:client_out.write(line)client_out.flush()client_sock.close()def echo_server(address):sock = socket(AF_INET, SOCK_STREAM)sock.bind(address)sock.listen(1)while True:client, addr = sock.accept()echo_client(client, addr)

需要重点强调的一点是,上面的例子仅仅是为了演示内置的 open() 函数的一个特性,并且也只适用于基于 Unix 的系统。如果你想将一个类文件接口作用在一个套接字并希望你的代码可以跨平台,请使用套接字对象的 makefile() 方法。但是如果不考虑可移植性的话,那上面的解决方案会比使用 makefile() 性能更好一点。

你也可以使用这种技术来构造一个别名,允许以不同于第一次打开文件的方式使用它。例如,下面演示如何创建一个文件对象,它允许你输出二进制数据到标准输出 (通常以文本模式打开):

import sys# Create a binary-mode file for stdout
bstdout = open(sys.stdout.fileno(), 'wb', closefd=False)
bstdout.write(b'Hello World\n')
bstdout.flush()

尽管可以将一个已存在的文件描述符包装成一个正常的文件对象,但是要注意的是并不是所有的文件模式都被支持,并且某些类型的文件描述符可能会有副作用 (特别是涉及到错误处理、文件结尾条件等等的时候)。在不同的操作系统上这种行为也是不一样,特别的,上面的例子都不能在非 Unix 系统上运行。我说了这么多,意思就是让你充分测试自己的实现代码,确保它能按照期望工作。

《Python Cookbook 3rd》笔记(5.18):将文件描述符包装成文件对象相关推荐

  1. python 将文件描述符包装成文件对象

    有一个对应于操作系统上一个已打开的I/O 通道(比如文件.管道.套接字等)的整型文件描述符,你想将它包装成一个更高层的Python 文件对象. 一个文件描述符和一个打开的普通文件是不一样的.文件描述符 ...

  2. linux文件描述符与标识符,文件描述符fd

    这里以问答的方式来讨论这个问题: 1. 文件描述符 fd 和文件指针 FILE *的关系? 文件描述符是什么?我们知道每一个进程都有一个自己的PCB(进程控制块),进程控制块的结构是: struct ...

  3. Linux中的文件描述符与打开文件之间的关系

    1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是 ...

  4. linux c中的文件描述符与打开文件之间的关系

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通 ...

  5. 文件描述符与打开文件的关系

    所有执行I/O操作的系统调用都以文件描述符,即一个非负整数来指代所打开的文件.文件描述符可以用来表示所有类型的已打开文件.同时,多个文件描述符可以指向同一个打开文件,因为有在不同进程中打开同一个文件的 ...

  6. linux 文件指针,Linux中文件描述符fd与文件指针FILE*互相转换实例解析

    本文研究的主要是Linux中文件描述符fd与文件指针FILE*互相转换的相关内容,具体介绍如下. 1.文件描述符fd的定义:文件描述符在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进 ...

  7. 文件描述符fd和文件指针File* fp的区别和转换

    在linux系统中把设备和普通文件也都看做是文件,要对文件进行操作就必须先打开文件,打开文件后会得到一个文件描述符,它是一个很小的正整数,是一个索引值.  内核会为每一个运行中的进程在进程控制块pcb ...

  8. Linux下多个进程可以同时打开同一个文件吗?文件描述符与打开文件的关系?

    一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程可以通过系统调用对文件加锁,从而实现对文件内容的保护 4.任何一个进程删 ...

  9. 文件描述符fd、文件指针fp和vfork()

    1. fd:在形式上是一个非负整数.实际上他是一个索引值.指向kernal为每一个进程所维护的该进程打开文件的记录表. 当程序打开一个文件或者创建一个新文件的时候kernal向进程返回一个文件描述符. ...

最新文章

  1. jquery autocomplete实现solr查询字段自动填充并执行查询
  2. 微信小程序实现图片是上传、预览功能
  3. mysql sql left right inner join区别及效率比较
  4. 共享一个调用微信公众平台接口的客户端类库
  5. spring,Whitelabel Error Page,This application has no explicit mapping for /error, so you are seeing
  6. net下web开发人员要掌握哪些技术才算好
  7. 牛客练习赛46 B 华华送奕奕小礼物 (预处理前缀和,二分)
  8. 将命令结果赋给变量_不得不了解的quot;变量quot;(2)—— 变量的赋值
  9. 电脑重装系统按哪个键
  10. zabbix3.0.4监控mysql主从同步
  11. python路径设置方法,R不转义,以及r转义出错SyntaxError
  12. 计算机网络dns实验报告,计算机网络DNS以及HTTP协议实验报告
  13. 音乐计算机官方.,Boom音乐电脑版
  14. 【现控】系统状态空间表达式
  15. 华为一碰传多屏协同(非华为电脑版)最新版安装教程【华为电脑管家11】【SN码修复】【NFC卡贴修复】
  16. 人工智能表格票据识别-要素信息自动识别提取
  17. Matlab数据线性化
  18. 2021 写博客指南·万字长文警告
  19. mysql failover_MySQL 8.0.22 新特性Async Replication Auto failover
  20. VO,DTO,BO,POJO,PO的概念介绍

热门文章

  1. centos 6 安装mysql,CentOS6.5安装MySQL教程(完整教程)
  2. 安卓文件共享服务器,安卓文件共享云服务器
  3. php二维码存放json数据_PHP生成及获取JSON文件的方法
  4. 【转】3.2(译)构建Async同步基元,Part 2 AsyncAutoResetEvent
  5. SQL SERVER data tier application 的作用及如何使用SSDT进行SQL数据库的自动化部署到生产环境和版本控制
  6. nginx文件系统大小_Nginx 了解一下?
  7. Qt使用导出类报错:error C2491: “ZMapWidget::staticMetaObject”: 不允许 dllimport 静态数据成员 的定义
  8. PWN-PRACTICE-BUUCTF-19
  9. 【LeetCode - 141142】环形链表(i和ii)(快慢指针,链表)
  10. 【CodeForces - 1197C】Array Splitting(水题)