国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

OverflowError: string longer than 2147483647 bytes

Godtoy / 3986人閱讀

摘要:問題簡述使用上傳文件時報錯誤問題代碼分析過程將全部讀入內存了沒想到的實現這么粗暴直接實際也是如此發送大文件時內存快速上漲代碼如下這里將所有文件都讀入內存官方文檔推薦使用使用的寫法總結的發送文件的實現

問題 簡述

requests 2.21.0
requests-toolbelt 0.9.1
使用python requests上傳文件時, 報
OverflowError: string longer than 2147483647 bytes 錯誤.

detail

問題代碼

    data = {}
    with open("bigfile", "rb") as f:
        r = requests.post(PUBLISH_URL, data=data, files={"xxx": f})
traceback
Traceback (most recent call last):
  File "test.py", line 52, in 
    main()
  File "test.py", line 49, in main
    publish()
  File "test.py", line 41, in publish
    r = requests.post(PUBLISH_URL, data=cfg, files={file_key: ("./test.apk", f)})
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 116, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 354, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python2.7/httplib.py", line 1057, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 1097, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 1053, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 897, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 873, in send
    self.sock.sendall(data)
  File "/usr/lib/python2.7/ssl.py", line 743, in sendall
    v = self.send(data[count:])
  File "/usr/lib/python2.7/ssl.py", line 709, in send
    v = self._sslobj.write(data)
OverflowError: string longer than 2147483647 bytes
分析過程 requests 將file obj 全部讀入內存了

沒想到requests的實現這么粗暴, 直接file.read(), 實際也是如此, 發送大文件時, 內存快速上漲. 代碼如下:
requests/models.py

    @staticmethod
    def _encode_files(files, data):
        """Build the body for a multipart/form-data request.

        Will successfully encode files when passed as a dict or a list of
        tuples. Order is retained if data is a list of tuples but arbitrary
        if parameters are supplied as a dict.
        The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
        or 4-tuples (filename, fileobj, contentype, custom_headers).
        """
        if (not files):
            raise ValueError("Files must be provided.")
        elif isinstance(data, basestring):
            raise ValueError("Data must not be a string.")

        new_fields = []
        fields = to_key_val_list(data or {})
        files = to_key_val_list(files or {})

        for field, val in fields:
            if isinstance(val, basestring) or not hasattr(val, "__iter__"):
                val = [val]
            for v in val:
                if v is not None:
                    # Don"t call str() on bytestrings: in Py3 it all goes wrong.
                    if not isinstance(v, bytes):
                        v = str(v)

                    new_fields.append(
                        (field.decode("utf-8") if isinstance(field, bytes) else field,
                         v.encode("utf-8") if isinstance(v, str) else v))

        for (k, v) in files:
            # support for explicit filename
            ft = None
            fh = None
            if isinstance(v, (tuple, list)):
                if len(v) == 2:
                    fn, fp = v
                elif len(v) == 3:
                    fn, fp, ft = v
                else:
                    fn, fp, ft, fh = v
            else:
                fn = guess_filename(v) or k
                fp = v

            if isinstance(fp, (str, bytes, bytearray)):
                fdata = fp
            elif hasattr(fp, "read"):
                fdata = fp.read() # 這里將所有文件都讀入內存
            elif fp is None:
                continue
            else:
                fdata = fp

            rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
            rf.make_multipart(content_type=ft)
            new_fields.append(rf)

        body, content_type = encode_multipart_formdata(new_fields)

        return body, content_type
官方文檔推薦使用requests-toolbelt

https://2.python-requests.org...

In the event you are posting a very large file as a multipart/form-data request, you may want to stream the request. By default, requests does not support this, but there is a separate package which does - requests-toolbelt. You should read the toolbelt’s documentation for more details about how to use it.
使用requests-toolbelt的寫法
from requests_toolbelt import MultipartEncoder

    data = {}
    with open("bigfile", "rb") as f:
        data["xxx"] = ("filename", f)
        m = MultipartEncoder(fields=data)
        r = requests.post(PUBLISH_URL, data=m, headers={"Content-Type": m.content_type})
總結

requests的發送文件的實現十分粗暴, 會直接讀全部文件內容到內存再sign, ssl sign大于2GB會報錯, 官方文檔推薦使用requests-toolbelt上傳大文件.
分塊上傳當然也是一個方案(如果服務器支持).

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43650.html

相關文章

  • Python標準庫---10、內置類型:數字類型

    摘要:上一篇文章標準庫內置類型邏輯值檢測布爾運算比較下一篇文章標準庫內置類型迭代器類型序列類型數字類型存在三種不同的數字類型整數浮點數和復數。標準庫包含附加的數字類型,如表示有理數的以及以用戶定制精度表示浮點數的。 上一篇文章:Python標準庫---9、內置類型:邏輯值檢測、布爾運算、比較下一篇文章:Python標準庫---11、內置類型:迭代器類型、序列類型 數字類型 --- int,...

    NotFound 評論0 收藏0
  • Python基礎——數據類型

    摘要:本文講解常用種數據類型通過剖析源碼弄清楚每一種數據類型所有的內置函數,理解每一個函數的參數返回值使用場景是什么。 本文講解Python常用7種數據類型:int, float, str, list, set, dict. 通過剖析源碼弄清楚每一種數據類型所有的內置函數,理解每一個函數的參數、返回值、使用場景是什么。 一、整型 int Python3.6源碼解析 class int(obj...

    ymyang 評論0 收藏0
  • 6. Java 中的基本數據類型 【連載 6】

    摘要:字符串和基本數據類型也能通過進行拼接操作,比如字符串的內容為。即基本類型和字符串類型相加時,基本類型會自動轉換為其字符串表示,在這個例子中相當于回顧包裝類這一小節的代碼類型的最大值就是將字符串和數據類型的拼接。 數據類型定義了變量可以采用的值,例如,定義變量為 int 類型,則只能取整數值。 在 Java 中有兩類數據類型: 1)原始數據類型 2)非原始數據類型 - 數組和字符串是非原...

    Kerr1Gan 評論0 收藏0
  • Java 之路 - JDK基礎 java.lang.Integer

    摘要:靜態常量,的長度,值為,單位為位。字節位最大值和最小值進制的次方進制的次方類型聲明為,所以可以直接使用類反射方法。普通方法轉成其他基本類型,,超過范圍會符號取反。和將字符串轉為進制整數。 靜態常量 Integer.SIZE,Integer.BYTES SIZE: Integer的長度,值為32,單位為位(bit)。BYTES:Integer的字節數,值為8,單位為字節(byte)。 1...

    劉玉平 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<