2009-12-04 11 views
2

j'ai cette fonction dans Delphi 2009/2010lecture de pages web/unicode

Il retourne ordures, maintenant si je change le char, les types PChar à AnsiChar, PAnsiChar il renvoie le texte mais tout le texte unicode étranger est ordures. il me conduire banane J'ai essayé toutes sortes de choses pendant 2 jours maintenant je pensais que j'understoff cette merde unicode mais je suppose que je ne aide s'il vous plaît merci Philippe Watel

function GetInetFileAsString(const fileURL: string): string; 
const 
    C_BufferSize = 1024; 
var 
    sAppName: string; 
    hSession, 
    hURL: HInternet; 

    Buffer: array[0..C_BufferSize] of Char; 
    BufferLen: DWORD; 

    strPageContent: string; 
    strTemp: string; 

begin 
    Result := ''; 
    sAppName := ExtractFileName(Application.ExeName); 
    hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, 
    nil, 0); 
    try 
    hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0); 
    try 
     strPageContent := ''; 
     repeat 
     InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen); 
     SetString(strTemp, PChar(@buffer), BufferLen div SizeOf(Char)); 
     strPageContent := strPageContent + strTemp; 
     until BufferLen = 0; 
     Result := strPageContent; 
    finally 
     InternetCloseHandle(hURL) 
    end 
    finally 
    InternetCloseHandle(hSession) 
    end 
end; 

Répondre

0

Ma première pensée est pour ajouter l'en-tête AcceptEncoding/CharSet correct de la demande:

par exemple:

Accept-Charset: ISO-8859-1, utf-8; q = 0,7, *; q = 0,7

4

À partir de Delphi 2009, String est un alias pour UnicodeString, qui contient des données UTF-16. D'autre part, une page HTML est généralement encodée en utilisant un codage Ansi multi-octets (habituellement UTF-8 de nos jours, mais pas toujours). Votre code actuel ne fonctionnera que si le code HTML est encodé en UTF-16, ce qui est très rare. Vous ne devriez pas lire directement les octets HTML bruts dans un UnicodeString. Vous devez d'abord télécharger l'intégralité des données dans un TBytes, RawByteString, TMemoryStream, ou un autre conteneur d'octets approprié de votre choix, puis effectuer une conversion Ansi-> Unicode par la suite, en fonction du jeu de caractères spécifié dans le HTTP "Content-Type". "en-tête de réponse. Vous pouvez utiliser l'en-tête de requête Accept-charset pour indiquer au serveur le charset dans lequel vous préférez que les données soient envoyées, et si le serveur ne peut pas utiliser ce jeu de caractères, il doit envoyer une réponse 406 Not Acceptable (bien que le message charset inacceptable s'il choisit d'ignorer votre en-tête de requête, vous devriez donc en tenir compte).

Essayez quelque chose comme ceci:

function GetInetFileAsString(const fileURL: string): string; 
const 
    C_BufferSize = 1024; 
var 
    sAppName: string; 
    hSession, hURL: HInternet; 
    Buffer: array of Byte; 
    BufferLen: DWORD; 
    strHeader: String; 
    strPageContent: TStringStream; 
begin 
    Result := ''; 
    SetLength(Buffer, C_BufferSize); 
    sAppName := ExtractFileName(Application.ExeName); 
    hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); 
    try 
    strHeader := 'Accept-Charset: utf-8'#13#10; 
    hURL := InternetOpenURL(hSession, PChar(fileURL), PChar(strHeader), Length(strHeader), 0, 0); 
    try 
     strPageContent := TStringStream.Create('', TEncoding.UTF8); 
     try 
     repeat 
      if not InternetReadFile(hURL, PByte(Buffer), Length(Buffer), BufferLen) then 
      Exit; 
      if BufferLen = 0 then 
      Break; 
      strPageContent.WriteBuffer(PByte(Buffer)^, BufferLen); 
     until False; 
     Result := strPageContent.DataString; 
     // or, use HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) to get 
     // the Content-Type header, parse out its "charset" attribute, 
     // and convert strPageContent.Memory to UTF-16 accordingly... 
     finally 
     strPageContent.Free; 
     end; 
    finally 
     InternetCloseHandle(hURL); 
    end 
    finally 
    InternetCloseHandle(hSession); 
    end; 
end; 
+0

J'ai utilisé ce code avec succès, mais je changer la mémoire tampon à un tableau dynamique déclaré tampon: tarray ; puis SetLength (buffer, C_BufferSize). De plus, j'ai ajouté un paramètre entier var à zéro avant la boucle et incrémenté avec bufferLen après chaque appel à InternetReadFile. Le permet de connaître la taille du fichier téléchargé. – MarkAurelius