下载字符串的编码问题UTF-8、ISO-8859-1、FSharp.Data

问题描述

我正在使用 FSharp.Data 下载和解析 XML 文档。该文件包含几个北欧字符,例如:“Lempäälän Keskus”。我有一个像这样的简单代码

open FSharp.Data
open System.IO

let xml = Http.RequestString(downloadUrl)
File.WriteallText("response.xml",xml)

但是,当我打开生成文件时,字符已损坏,我看到:“Lempäälän Keskus”。我尝试使用 ISO-8859-1 编码手动重新保存文件,然后使用 UTF-8(在 VS Code 中)重新打开。这修复了显示的文本。然后尝试实现一个简单的编码转换功能

open FSharp.Data
open System
open System.IO

let convertEncoding (input: string) =
  let iso = Encoding.GetEncoding("ISO-8859-1")
  let utf8 = Encoding.UTF8
  let isoBytes = iso.GetBytes(input)
  let utfBytes = Encoding.Convert(iso,utf8,isoBytes)
  utf8.GetString(utfBytes)

let xml = Http.RequestString(downloadUrl)
let decoded = convertEncoding xml
File.WriteallText("response.xml",decoded)

但是,当我打开文件时,我仍然看到“Lempäälän Keskus”而不是“Lempäälän Keskus”。我做错了什么?

解决方法

在向文件写入文本时提供编码

let encoding = Encoding.GetEncoding("ISO-8859-1")
File.WriteAllText("response.xml",xml,encoding)
,

实际上,这似乎是由 Http 库中的 FSharp.Data 客户端引起的奇怪行为。我不确定这是一个错误,还是只是我没有找到文档的功能。

FSharp.Data.Http 替换 System.Net.Http.HttpClient 客户端就足够了。突然间,所有的编码错误都消失了,不需要任何转换。这是一个示例解决方案:

open System
open System.IO
open System.Net.Http

let download (url: string) = 
  async {
    use client = new HttpClient()
    let! xml = client.GetStringAsync(url) 
                |> Async.AwaitTask
    return xml
  }

let result = download url |> Async.RunSynchronously
File.WriteAllText("response.xml",result)