无法隐式地将“bytes”对象转换为“str”

5

我正在尝试打开一个gif文件,并将其正确地发送到Web浏览器,但它抛出了异常“不能隐式转换'bytes'对象为str”,老实说,我感到困惑,因为我已经将它转换为字符串了。

files=open("WebContent/"+fileName,"rb")
#size=os.path.getsize("WebContent/"+fileName)
text=str(files.read())
text=text.encode('UTF-8')
defaultResponseCode="HTTP/1.1 200 OK\r\nContent-Type: image/gif\r\nContent-Transfer-Encoding: binary\r\nContent-Length: 29696\r\n\r\n"+text

事先感谢您!


1
text=text.encode('UTF-8') 现在它不再是一个字符串了... - tckmn
哦,所以我只需要写成'text.encode('UTF-8')'吗? - user1564622
1
为什么要转换成字符串?你不需要这样做。你的 Content-Transfer-Encoding 头部声称是“二进制”,因此数据上没有应用任何编码。将图像发送就像你从文件中读取它一样。 - Michael Foukarakis
3个回答

1

在这里,您正在尝试将字节(使用'rb'模式打开的文件)转换为字符串:

text = str(files.read())

将上面一行更改为以下内容:
text = files.read().decode(encoding='change_to_source_file_encoding')

然后,您可以使用以下方法将 Unicode 字符串转换为 UTF-8 字节字符串:
text = text.encode('UTF-8')

如果源编码是utf-8,您可以直接将files.read()的字节字符串传递到结果字符串中,而不需要无意义的解码/编码步骤(从utf-8字节转换为字符串,再次转换为utf-8字节)...
更新:尝试使用requests
url = 'url'
files = {'file': open("WebContent/"+fileName, 'rb')}
response = requests.post(url, files=files)

更新2:
根据响应头中的内容类型(... Content-Type: image/gif ...),在 files.read() 后面您将获得所需格式的数据,无需进行任何编码/解码!请注意保留 HTML 标签。

@user1564622 现在试试,你是用的Python3吗? - ndpu
我很困惑 - 你应该将其读取为字符串并将其用作字符串,或者将其读取为字节并将其用作字节。为什么两者都要? - Adam Smith
@user1564622的源文件采用utf-8编码吗?如果有错误,尝试使用errors='ignore'更改编码或解码方式:text = files.read().decode(encoding='utf8', 'ignore')。 - ndpu
不,我的意思是这种方法不合理。你让他读取一个文件作为字节,然后根据utf-8编码解码为字符串,然后重新将该字符串编码为字节,然后发送出去。@user1564622,如果您只需要将其作为字节发送到浏览器,则跳过str(files.read())调用,只需发送files.read()即可。如果您需要纯文本字符串,请保存到另一个变量中,而不是使用ndpu建议的files.read.decode(encoding='utf8') - Adam Smith
好的,底线是,有人能向我展示如何正确地读取文件并通过http发送它吗? - user1564622
如果是gif,你根本不需要使用字符串! - Max

0
在Python 3+中,我遇到了类似的问题,我删除了text.encode("utf-8")并使用了text.strip()
text = text.strip()

0

对于那些主要关注Popen而不是psql的人,这里有一个调试过的工作python3脚本,基于原始的Popen问题,并结合提供的建议。

#!/usr/bin/env python3

# print a list of postgresql databases via psql
import subprocess

username = "postgres"
dbname = "postgres"

p = subprocess.Popen(
  args = ['psql', '-qAt', '-U', username, '-d', dbname],
# args = ['psql', '-qAt', '-d', dbname], # with adequate user permissions
  stdin = subprocess.PIPE,
  stdout = subprocess.PIPE
)
sql = b"SELECT datname FROM pg_database;"

dbs = p.communicate(b"SELECT datname FROM pg_database;")[0].split(b'\n')

for db in dbs:
  print("%s" % db.decode("utf-8"))

p.wait() 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接