如何在R语言中不解压读取ISO-8859-15编码的压缩包内CSV文件
解决R中用
unz读取ISO-8859-15编码压缩文件的乱码问题 这个问题的核心原因其实是**unz()返回的是二进制连接,而非文本连接**——base R的readLines()和read.csv()这类函数,对于二进制连接会直接读取原始字节,忽略你传入的encoding或fileEncoding参数,所以才会出现特殊字符显示为十六进制转义符(比如\xe3)的情况。而直接用file()时,它创建的是文本连接,会自动按指定编码转码,所以能正常显示特殊字符。
下面给你几个可行的解决方案:
方案1:手动读取字节后转码(base R原生实现)
先读取压缩文件里的原始二进制字节,再用iconv()转成正确的编码,之后再处理文本/CSV内容:
file_zip <- "test.zip" file_txt <- "test.txt" # 1. 读取原始二进制字节 conn <- unz(file_zip, file_txt) # 获取文件大小,确保读取全部内容 file_size <- file.info(conn)$size raw_bytes <- readBin(conn, raw(), n = file_size) close(conn) # 2. 转码为ISO-8859-15到R默认的UTF-8 text_content <- iconv(rawToChar(raw_bytes), from = "ISO-8859-15", to = "") # 查看结果 cat(text_content) # 输出 testãóçáà # 如果是CSV文件,转码后用text参数传入read.csv csv_text <- iconv(rawToChar(readBin(unz(file_zip, "data.csv"), raw(), n = file.info(unz(file_zip, "data.csv"))$size)), from = "ISO-8859-15", to = "") df <- read.csv(text = csv_text, header = TRUE)
方案2:用readr包简化处理(推荐)
readr包的读取函数(比如read_csv、read_lines)能更好地处理二进制连接的编码问题,只需要通过locale参数指定编码即可:
# 先安装包(如果没装过) install.packages("readr") library(readr) # 读取文本文件 text_lines <- read_lines(unz(file_zip, file_txt), locale = locale(encoding = "ISO-8859-15")) print(text_lines) # 输出 "testãóçáà" # 读取CSV文件 df <- read_csv(unz(file_zip, "data.csv"), locale = locale(encoding = "ISO-8859-15"), show_col_types = FALSE)
方案3:用zip包读取原始内容后转码
zip包提供了更简洁的压缩文件读取接口,同样需要手动转码:
install.packages("zip") library(zip) # 读取原始字节 raw_content <- zip_read(file_zip, file_txt) # 转码 text_content <- iconv(rawToChar(raw_content), from = "ISO-8859-15", to = "")
为什么你之前的尝试无效?
当你直接把unz()的连接传给read.csv()并指定encoding或fileEncoding时,base R的read.csv()会把这个连接当作二进制流处理,不会应用编码转换——这些参数只对文本连接(比如file()创建的连接)生效。这就是为什么你用file()时正常,用unz()时乱码的原因。
内容的提问来源于stack exchange,提问作者Rodrigo Lustosa
相关产品推荐
相关产品推荐

