【问题标题】:Python - Write in text mode to file opened in binary modePython - 以文本模式写入以二进制模式打开的文件
【发布时间】:2020-12-18 09:49:07
【问题描述】:

我是出于好奇才问这个的。

我在做什么:

  • 创建临时文件
  • 使用to_csv() 将数据从 Pandas 数据帧写入其中
  • 将文件推送到 FTP 服务器

由于tempfile 默认以二进制模式打开,但to_csv() 方法默认以文本模式写入(我需要它,因为我希望将 UTF-8 作为格式)我问自己如何编写在文本模式到以二进制模式打开的文件?我还需要二进制格式来传输到 FTP 服务器。

我做了什么:

我创建了一个这样的临时文件:

fp = tempfile.NamedTemporaryFile(delete=False)

据我所知,documentation 文件是以二进制模式打开的。

tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None)

然后我像这样将我的数据框保存到临时文件中:

df.to_csv(fp.name)
fp.flush()
fp.seek(0)

另外to_csv() 方法在documentation 中声明您需要使用newlines='' 打开文件,该文件仅适用于文本模式。所以我无法使用以二进制模式打开的文件设置newline 参数。

path_or_bufstr 或文件句柄,默认无 文件路径或对象,如果提供 None 则结果作为字符串返回。如果传递了文件对象,则应使用newline='' 打开它,禁用通用换行符。

然后我使用 ftplib 中的storbinary() 方法将临时文件推送到 FTP 服务器。据我从documentation 了解到,该方法需要一个二进制文件。

FTP.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None) 以二进制传输模式存储文件。 cmd 应该是适当的 STOR 命令:"STOR filename"fp 是一个文件对象(以二进制模式打开),使用其read() 方法在大小为blocksize 的块中读取直到EOF,以提供要存储的数据。 blocksize 参数默认为 8192。callback 是一个可选的可调用单参数,在发送后对每个数据块进行调用。 rest 与 transfercmd() 方法中的含义相同。

为了完整起见,我随后关闭并删除了这样的文件:

fp.close()
os.unlink(fp.name)

我考虑过在w+t 模式下打开tempfile,使其与to_csv() 方法相匹配,该方法建议使用仅在文本模式下有效的newlines='' 打开文件。我还需要为仅在文本模式下工作的 CSV 文件指定 UTF-8 格式。 ftplib 的storbinary() 方法需要以二进制模式打开文件。 (storlines() 方法也可以)所以这不合适。

所以我以二进制模式打开文件,以文本模式写入文件并使用二进制模式传输。一切正常,结果看起来像我想要的,但如果我以正确的方式做,我会有点困惑。如何以文本模式写入以二进制模式打开的文件?我有点假设我必须以文本模式打开文件才能使用 to_csv() 以文本模式写入文件。

如果有人对此有更深入的了解并能解决我的困惑,我将不胜感激。我不喜欢做不知道为什么工作或是否应该工作的事情哈哈。

谢谢!

【问题讨论】:

    标签: python pandas csv ftp ftplib


    【解决方案1】:

    这是一个相当广泛的问题。简单地说。这主要是关于行尾。这基本上是二进制和文本模式之间的唯一区别。

    • 如果您以二进制模式“打开”文件,所有数据都将按原样写入。如果您以文本模式打开文件,则换行符 (\n) 将根据 newline 参数进行转换。
    • 我认为 Pandas 不需要以文本模式打开文件。如果您以二进制模式打开文件,那么 Pandas 写入的任何内容都将在文件中物理结束。请参阅DataFrame.to_csvline_terminatorstr 参数。
    • 与 FTP 基本相同。如果您使用storbinary,文件将按原样上传。如果使用storlines,则让 FTP 服务器转换行尾。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      相关资源
      最近更新 更多