You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SFTP上传JSON内容时遇类型错误与属性错误的问题

问题解决:SFTP上传JSON数据时的两个错误处理

原始需求

要上传的目标数据结构:

sample = {'Details': [{'user1': '{"d8": "X121", "d0": "NIL", "d4": false, "d3": false, "d2": false}', 'name': 'set a sample'}], 'person1': 1} 

第一次尝试的代码及错误

代码

s1 = json.dumps(sample).replace('"', '"').replace("'", "'")
ftp = ssh.open_sftp()
ftp.putfo(BytesIO(s1), 'newfile.txt')

错误信息

Reason: <class 'TypeError'> a bytes-like object is required, not 'str'

第二次修改后的代码及错误

代码

import json
per_json = {'d8': 'X121',
    'd0': 'NIL',
    'd4': False,
    'd3': False,
    'd2': False}
p1 = {
    "name" : "set a sample"
}

p1["additional_info"] = json.dumps(per_json)
p1_list={"person1":1}
p1_list["Details"]=[p1]
s1 = json.dumps(p1_list).replace('}"', "}").replace('"{', "{").replace('\\"', '"')
ftp = ssh.open_sftp()
ftp.putfo(s1, 'newfile.txt')
ftp.close()

错误信息

Reason: <class 'AttributeError'> 'str' object has no attribute 'read'


错误原因及解决方法

第一个错误:TypeError: a bytes-like object is required, not 'str'

原因:BytesIO 要求传入字节类型数据,但你传入的是字符串。json.dumps() 返回的是字符串,直接传给 BytesIO 会触发类型错误。
解决:把字符串通过 str.encode('utf-8') 转成字节,再传入 BytesIO。

第二个错误:AttributeError: 'str' object has no attribute 'read'

原因:ftp.putfo() 的第一个参数必须是类文件对象(拥有read()方法的对象),直接传字符串不符合要求,因为字符串没有read()方法。
解决:将字符串包装成BytesIO或StringIO实例,再传给putfo()。


最终正确代码

针对原始需求的正确上传代码,无需多余的字符串替换操作(json.dumps()会自动处理格式,手动替换反而容易破坏JSON结构):

import json
from io import BytesIO

# 原始目标数据
sample = {
    'Details': [
        {
            'user1': '{"d8": "X121", "d0": "NIL", "d4": false, "d3": false, "d2": false}',
            'name': 'set a sample'
        }
    ],
    'person1': 1
}

# 序列化JSON并转成字节流类文件对象
json_str = json.dumps(sample)
file_like_obj = BytesIO(json_str.encode('utf-8'))

# SFTP上传
ftp = ssh.open_sftp()
ftp.putfo(file_like_obj, 'newfile.txt')
ftp.close()

如果使用你修改后的p1_list结构,代码逻辑一致:

import json
from io import BytesIO

per_json = {'d8': 'X121', 'd0': 'NIL', 'd4': False, 'd3': False, 'd2': False}
p1 = {"name": "set a sample"}
p1["additional_info"] = json.dumps(per_json)
p1_list = {"person1": 1, "Details": [p1]}

# 序列化+转字节+包装成类文件对象
json_str = json.dumps(p1_list)
file_like_obj = BytesIO(json_str.encode('utf-8'))

ftp = ssh.open_sftp()
ftp.putfo(file_like_obj, 'newfile.txt')
ftp.close()

关键注意点

  1. BytesIO 必须接收字节类型数据,字符串需通过encode()转换。
  2. putfo() 仅接受类文件对象,不能直接传字符串。
  3. 避免无意义的字符串替换:json.dumps()会自动处理引号转义,手动修改会破坏JSON格式。

内容的提问来源于stack exchange,提问作者aΨVaN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:55:18