开发者社区> 问答> 正文

从C语言中读取类文件对象

你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件、StringIO对象等)。

展开
收起
哦哦喔 2020-04-17 18:17:13 3091 0
2 条回答
写回答
取消 提交回答
  • 有点尴尬唉 你要寻找的东西已经被吃掉啦!

    从C语言中读取类文件对象:可以参考这篇文章: https://www.baidu.com/link?url=6djl4oF9q-bjXsKIc7n5xA5eoO3YbD_ISURCaytWx9o0B2dmmEhXclgxb_R 图片.png

    2020-04-17 23:55:28
    赞同 展开评论 打赏
  • 要读取一个类文件对象的数据,你需要重复调用 read() 方法,然后正确的解码获得的数据。
    
    下面是一个C扩展函数例子,仅仅只是读取一个类文件对象中的所有数据并将其输出到标准输出:
    
    #define CHUNK_SIZE 8192
    
    /* Consume a "file-like" object and write bytes to stdout */
    static PyObject *py_consume_file(PyObject *self, PyObject *args) {
      PyObject *obj;
      PyObject *read_meth;
      PyObject *result = NULL;
      PyObject *read_args;
    
      if (!PyArg_ParseTuple(args,"O", &obj)) {
        return NULL;
      }
    
      /* Get the read method of the passed object */
      if ((read_meth = PyObject_GetAttrString(obj, "read")) == NULL) {
        return NULL;
      }
    
      /* Build the argument list to read() */
      read_args = Py_BuildValue("(i)", CHUNK_SIZE);
      while (1) {
        PyObject *data;
        PyObject *enc_data;
        char *buf;
        Py_ssize_t len;
    
        /* Call read() */
        if ((data = PyObject_Call(read_meth, read_args, NULL)) == NULL) {
          goto final;
        }
    
        /* Check for EOF */
        if (PySequence_Length(data) == 0) {
          Py_DECREF(data);
          break;
        }
    
        /* Encode Unicode as Bytes for C */
        if ((enc_data=PyUnicode_AsEncodedString(data,"utf-8","strict"))==NULL) {
          Py_DECREF(data);
          goto final;
        }
    
        /* Extract underlying buffer data */
        PyBytes_AsStringAndSize(enc_data, &buf, &len);
    
        /* Write to stdout (replace with something more useful) */
        write(1, buf, len);
    
        /* Cleanup */
        Py_DECREF(enc_data);
        Py_DECREF(data);
      }
      result = Py_BuildValue("");
    
     final:
      /* Cleanup */
      Py_DECREF(read_meth);
      Py_DECREF(read_args);
      return result;
    }
    要测试这个代码,先构造一个类文件对象比如一个StringIO实例,然后传递进来:
    
    >>> import io
    >>> f = io.StringIO('Hello\nWorld\n')
    >>> import sample
    >>> sample.consume_file(f)
    Hello
    World
    >>>
    
    2020-04-17 18:17:22
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载