首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我不能打开用此代码复制的pdf文件?

为什么我不能打开用此代码复制的pdf文件?
EN

Stack Overflow用户
提问于 2014-06-12 17:43:51
回答 2查看 466关注 0票数 0

我需要做一些操作,一些pdf文件。作为第一步,我希望将它们从一个目录复制到支持我的需求的树中。我使用了以下代码

代码语言:javascript
复制
for doc in docList:
    #          these steps just create the directory structure I need from the file name
    fileName = doc.split('\\')[-1]
    ID = fileName.split('_')[0]
    basedate = fileName.split('.')[0].split('_')[-1].strip()
    rdate = '\\R' + basedate + '-' +'C' + basedate
    newID = str(cikDict[ID])
    newpath = basePath + newID + rdate
    #            check existence of the new path
    if not os.path.isdir(newpath):
        os.makedirs(newpath)
    #          reads the file in and then writes it to the new directory   
    fstring = open(doc).read()
    outref = open(newpath +'\\' + fileName, 'wb')
    outref.write(fstring)
    outref.close()

当我运行此代码时,将创建目录,每个目录中都有具有正确名称的文件。但是,当我单击打开一个文件时,我从Acrobat获得一个错误,通知我该文件已损坏,无法修复。

我能够用

代码语言:javascript
复制
shutil.copy(doc,newpath) 

来替换最后四行,但我一直无法弄清楚为什么不能将文件作为字符串读取,然后将其写入新的位置。

我所做的一件事是将从源读取的内容与在写入文件后读取文件内容的内容进行比较:

代码语言:javascript
复制
>>> newstring = open(newpath + '\\' +fileName).read()
>>> newstring == fstring
True

所以它没有出现内容被更改?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-12 17:58:39

您应该使用舒蒂尔复制文件。它是平台感知的,您可以避免这样的问题。

但你已经发现了。

使用使用可以更好地打开和关闭文件。然后自动打开和关闭文件。这是比较惯用的:

代码语言:javascript
复制
with open(doc, 'rb') as fin, open(fn_out, 'wb') as fout:
    fout.write(fin.read())                     # the ENTIRE file is read with .read()

如果您可能正在处理一个大文件,请用块读取和写入:

代码语言:javascript
复制
with open(doc, 'rb') as fin, open(fn_out, 'wb') as fout:
    while True:
        chunk=fin.read(1024)
        if chunk:
             fout.write(chunk)
        else:
             break

注意打开的'rb‘和'wb’参数。由于您显然是在Windows下打开该文件,因此无法将该文件解释为Windows字符串。

您还应该使用os.path.join而不是newpath + '\\' +fileName类型的操作。

票数 1
EN

Stack Overflow用户

发布于 2014-06-13 07:33:27

我无法弄清楚为什么不能将文件作为字符串读取,然后将其写入新的位置。

请注意,PDF是二进制文件格式,而不是文本文件格式。将文件(或一般数据)作为文本处理的方法可能会以不同的方式更改它,特别是:

  • 读取数据作为文本,根据一定的字符编码将字节和字节序列解释为字符。将文本写回数据,也会根据某些字符编码进行转换。 如果应用的编码不同,则结果显然与原始文件不同。但是,即使使用了相同的编码,差异也可能蔓延进来:如果原始文件包含在应用的编码中没有意义的字节,则使用一些替换字符,最后的结果文件包含该替换字符的编码,而不是原始字节序列。此外,有些编码对于同一字符有多个可能的编码。因此,可以将一些输入字节序列替换为表示输出中相同字符的其他序列。
  • 线尾序列可以根据平台的喜好而改变. 二进制文件可能包含在一个或另一个平台上用作行尾标记的不同字节序列,例如CR、LF、CRLF、.方法将数据作为文本处理,可以用本地平台上喜欢的一个序列替换所有数据。但是,由于二进制文件中的这些字节的含义可能与行尾不同,这种替换可能具有破坏性。
  • 一般情况下可以忽略控制字符。 在许多编码中,字节0..31具有控制字符的含义。方法将二进制数据作为文本处理,以某种方式对其进行解释,从而可能导致再次发生变化的输出。

所有这些更改都会彻底破坏二进制数据,例如PDF中的压缩流。

您可以尝试使用二进制模式读取文件,方法是在模式字符串中使用b打开它们。在阅读和书写时使用二进制模式可以解决您的问题。

我所做的一件事是将从源代码读取的内容与在写入文件后读取后的文件内容进行比较:newstring = open(newpath + '\‘+文件名).read() >>>新字符串== fstring True 所以它没有出现内容被更改?

您的比较还会将文件读取为文本。因此,您不需要比较原始文件和复制文件的实际字节内容,而是根据读取它们时假定的编码对它们的解释。所以损害已经在你的比较的双方都做了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24190712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档