<sub id="73hld"><meter id="73hld"></meter></sub><rp id="73hld"><big id="73hld"><listing id="73hld"></listing></big></rp>

    <th id="73hld"><meter id="73hld"><dfn id="73hld"></dfn></meter></th>

      <th id="73hld"></th>
          <th id="73hld"><form id="73hld"><dfn id="73hld"></dfn></form></th>
          書籍文庫  |  文檔資料  |  最近更新  |  MAP  |  TAG  | 
          注冊
          手機版
          就愛閱讀網
          當前位置:首頁 > 電腦辦公 > 電腦設計 > 程序設計 > D2010,indy10.5.5,一些問題解決方法

          D2010,indy10.5.5,一些問題解決方法

          分享人:beiqiao 來源:互聯網 時間:2018-10-15 11:22:49 閱讀:0

            剛從D7轉過來有點不習慣,到發貼時都沒搞懂string,ansistring,widestring的區別與具體使用環境。

            這里主要記錄一些在D2010中使用自帶INDY10.5.5  post網站的一些問題(主要用于發貼)。

            首先,與大家一樣,遇到的是使用TIdMultiPartFormDataStream,post中文變亂碼(這個亂碼不是UTF8那種亂碼,是一串“口”),網上說把IdMultipartFormData.pas中的IdRead函數修改,如下:

          復制代碼
          function TIdMultiPartFormDataStream.IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint;
          var
          LTotalRead: Integer;
          LCount: Integer;
          LBufferCount: Integer;
          LRemaining : Integer;
          LItem: TIdFormDataField;
          begin
          if not FInitialized then begin
          FInitialized := True;
          FCurrentItem := 0;
          SetLength(FInternalBuffer, 0);
          end;

          LTotalRead := 0;
          LBufferCount := 0;

          while (LTotalRead < ACount) and ((FCurrentItem < FFields.Count) or (Length(FInternalBuffer) > 0)) do begin
          if (Length(FInternalBuffer) = 0) and not Assigned(FInputStream) then begin
          LItem := FFields.Items[FCurrentItem];
          AppendString(FInternalBuffer, LItem.FormatField, TEncoding.Default);

          if Assigned(LItem.FieldObject) then begin
          if (LItem.FieldObject is TStream) then begin
          FInputStream := TStream(LItem.FieldObject);
          FInputStream.Position := 0;
          end else begin
          if (LItem.FieldObject is TStrings) then begin
          AppendString(FInternalBuffer, TStrings(LItem.FieldObject).Text, TEncoding.Default);
          Inc(FCurrentItem);
          end;
          end;
          end else begin
          Inc(FCurrentItem);
          end;
          end;

          if Length(FInternalBuffer) > 0 then begin
          if Length(FInternalBuffer) > (ACount - LBufferCount) then begin
          LCount := ACount - LBufferCount;
          end else begin
          LCount := Length(FInternalBuffer);
          end;

          if LCount > 0 then begin
          LRemaining := Length(FInternalBuffer) - LCount;
          CopyTIdBytes(FInternalBuffer, 0, VBuffer, LBufferCount, LCount);
          if LRemaining > 0 then begin
          CopyTIdBytes(FInternalBuffer, LCount, FInternalBuffer, 0, LRemaining);
          end;
          SetLength(FInternalBuffer, LRemaining);
          LBufferCount := LBufferCount + LCount;
          FPosition := FPosition + LCount;
          LTotalRead := LTotalRead + LCount;
          end;
          end;

          if Assigned(FInputStream) and (LTotalRead < ACount) then begin
          LCount := TIdStreamHelper.ReadBytes(FInputStream,VBuffer, ACount - LTotalRead, LBufferCount);
          if LCount < (ACount - LTotalRead) then begin
          FInputStream.Position := 0;
          FInputStream := nil;
          Inc(FCurrentItem);
          SetLength(FInternalBuffer, 0);
          AppendString(FInternalBuffer, #13#10);
          end;

          LBufferCount := LBufferCount + LCount;
          LTotalRead := LTotalRead + LCount;
          FPosition := FPosition + LCount;
          end;

          if FCurrentItem = FFields.Count then begin
          AppendString(FInternalBuffer, PrepareStreamForDispatch, TEncoding.Default);
          Inc(FCurrentItem);
          end;
          end;
          Result := LTotalRead;
          end;
          復制代碼

          紅色部分是修改部分,在調用AppendString時補齊第三個參數,值為 TEncoding.Default  但是未見成效。有成功的請告訴我應該怎么做,謝謝。

           

          最后無法,我使用了一個精簡的TMsMultiPartFormDataStream類,源碼如下:

           

          View Code

          注意,其中的字符串類型全是AnsiString,這個類和indy的TIdMultiPartFormDataStream用法一樣。

          用這個類添加中文,post后不會是亂碼,尚不明原因,求解釋。

            接下來的問題是,post UTF8編碼問題,在2009以前,str:=UTF8Encode('字符串'),會得到一個看著像亂碼的字符串,這是正確的,但是在2010中,str的結果還是“字符串”,所以用抓包工具看到的中文實際上也是編碼不成功的,在2010中想要得到正確的utf8字符串,應該:str:=UTF8EncodeToShortString('字符串'); 這個函數只能針對長度不超過255的中文有效,超過255的需要用下面的函數:

          復制代碼
          function Utf8Encode(const US: UnicodeString): AnsiString;
          var
          L: Integer;
          begin
          Result := '';
          if US = '' then Exit;
          L := Length(US);
          SetLength(Result, L *3);
          L := UnicodeToUtf8(PAnsiChar(Result), Length(Result) + 1, PWideChar(US), L);
          if L=0 then
          Result:='';
          end;
          復制代碼

            上面的函數不是system的utf8Encode,是根據自己需要改編自UTF8EncodeToShortString 和 UTF8Encode,其中SetLength(Result, L *3);長度X3是因為UTF-8長度為3。

           其中原理我也不清楚,反正這樣用沒錯,至于原理,還請知道的人告知,謝謝。 

            最后一個是GET UTF8編碼問題,在d7中,我經常這樣寫:

            str:=http.get(url);

            str:=utf8toansi(url);(utf8toansi不是系統自帶的函數,是自己寫的,系統自帶的utf8toansi其實是調用utf8decode,大多時候會把字符串變成空)

            在d2010中,上面的方式行不通,需要用到TStringStream,如果確實是utf8編碼則,st:=tStringStream.create('',TEncoding.UTF8); 如果不確定返回數據的編碼,則先

           http.get(url,st);

           //然后判斷編碼

            isutf8:=checkencoding(st.DataString,http.Response.ContentType);

            if isutf8 then

              str:=utf8tostring(st.DataString);

            當然,這樣也不是最完美的解決方法,經過utf8tostring后,一樣會有少數字符是“?”,以下附上自己用的checkEncoding;

          復制代碼
          function  CheckEncoding(s,ContentType:string):Boolean;
          var
          per:TPerlRegEx;
          begin
          if ansicontainstext(ContentType,'charset=utf-8') then
          begin
          result:=True;
          end
          else
          begin
          per:=TPerlRegEx.Create(nil);
          per.Options:=[preCaseLess];
          per.Subject:=s;
          per.RegEx:='<meta[\S\s]*?charset=(.*)>';
          if per.Match then
          if AnsiContainsText(per.MatchedExpression,'UTF-8') then
          begin
          result:=True;
          end;
          freeandnil(per);
          end;
          end;
          復制代碼

            以上只是個人拙見,歡迎斧正。


          百度搜索“就愛閱讀”,專業資料,生活學習,盡在就愛閱讀網92to.com,您的在線圖書館!

          熱點閱讀

          網友最愛

          吉林快三走势图

          <sub id="73hld"><meter id="73hld"></meter></sub><rp id="73hld"><big id="73hld"><listing id="73hld"></listing></big></rp>

            <th id="73hld"><meter id="73hld"><dfn id="73hld"></dfn></meter></th>

              <th id="73hld"></th>
                  <th id="73hld"><form id="73hld"><dfn id="73hld"></dfn></form></th>

                  <sub id="73hld"><meter id="73hld"></meter></sub><rp id="73hld"><big id="73hld"><listing id="73hld"></listing></big></rp>

                    <th id="73hld"><meter id="73hld"><dfn id="73hld"></dfn></meter></th>

                      <th id="73hld"></th>
                          <th id="73hld"><form id="73hld"><dfn id="73hld"></dfn></form></th>