• R语言已解决
  • Windows下打包的 zip 文件在 Ubuntu 下用 R 自带的 `unzip()` 解压报错

问题描述

我这里有两个中文命名的数据文件需要打包成 .zip 上传到服务器上。
Windows 下打包的 zip 文件在 Windows 下用 R 4.1.2 自带的 unzip() 解压是正常的。
Ubuntu 下打包的 zip 文件在 Ubuntu 下用 R 4.2.2 自带的 unzip() 解压也是正常的。
可是偏偏我将 shinyApp 部署到阿里云服务器(Ubuntu)上,然后在 Windows 下打包文件并上传后解压缩就问题了。

网上搜了下,如下 Linux 命令是可以正常解压缩 Windows 下打包的 zip 文件的:

unzip -O CP936 ziponwin.zip

但是 R 自带的 unzip() 貌似并没有定义 CP936 这样的参数设置。

报错信息

在 Ubuntu 下尝试用 unzip("./testzip/ziponwin.zip") 解压缩在 Windows 下打包的 zip 文件,报错信息如下:

Error in unzip("./testzip/ziponwin.zip") : 无法打开文件'./����.xlsx': 无效或不完整的多字节字符或宽字符

数据文件和代码

代码和数据文件地址:https://gitlab.com/chuxinyuan/unzip
测试文件在 testzip 文件夹下,其中 ziponwin.zip 是在 Win10 下打包的, ziponlinux.zip 是在 Ubuntu 下打包的。

系统环境

  • Ubuntu
xfun::session_info()
#> R version 4.2.2 Patched (2022-11-10 r83330)
#> Platform: x86_64-pc-linux-gnu (64-bit)
#> Running under: Ubuntu 20.04.5 LTS
#> 
#> Locale:
#>   LC_CTYPE=zh_CN.UTF-8       LC_NUMERIC=C              
#>   LC_TIME=zh_CN.UTF-8        LC_COLLATE=zh_CN.UTF-8    
#>   LC_MONETARY=zh_CN.UTF-8    LC_MESSAGES=zh_CN.UTF-8   
#>   LC_PAPER=zh_CN.UTF-8       LC_NAME=C                 
#>   LC_ADDRESS=C               LC_TELEPHONE=C            
#>   LC_MEASUREMENT=zh_CN.UTF-8 LC_IDENTIFICATION=C       
#> 
#> Package version:
#>   base64enc_0.1.3   bslib_0.4.2       cachem_1.0.6      callr_3.7.3      
#>   cli_3.6.0         clipr_0.8.0       compiler_4.2.2    digest_0.6.31    
#>   ellipsis_0.3.2    evaluate_0.20     fastmap_1.1.0     fs_1.6.1         
#>   glue_1.6.2        graphics_4.2.2    grDevices_4.2.2   highr_0.10       
#>   htmltools_0.5.4   jquerylib_0.1.4   jsonlite_1.8.4    knitr_1.42       
#>   lifecycle_1.0.3   magrittr_2.0.3    memoise_2.0.1     methods_4.2.2    
#>   mime_0.12         processx_3.8.0    ps_1.7.2          purrr_1.0.1      
#>   R.cache_0.16.0    R.methodsS3_1.8.2 R.oo_1.25.0       R.utils_2.12.2   
#>   R6_2.5.1          rappdirs_0.3.3    reprex_2.0.2      rlang_1.0.6      
#>   rmarkdown_2.20    rprojroot_2.0.3   rstudioapi_0.14   sass_0.4.5       
#>   stats_4.2.2       stringi_1.7.12    stringr_1.5.0     styler_1.9.0     
#>   tinytex_0.44      tools_4.2.2       utils_4.2.2       vctrs_0.5.2      
#>   withr_2.5.0       xfun_0.37         yaml_2.3.7

<sup>Created on 2023-02-18 with reprex v2.0.2</sup>

  • 单位 Windows
xfun::session_info()
#> R version 4.1.2 (2021-11-01)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 18363)
#> 
#> Locale:
#>   LC_COLLATE=Chinese (Simplified)_China.936 
#>   LC_CTYPE=Chinese (Simplified)_China.936   
#>   LC_MONETARY=Chinese (Simplified)_China.936
#>   LC_NUMERIC=C                              
#>   LC_TIME=Chinese (Simplified)_China.936    
#> 
#> Package version:
#>   backports_1.4.1   base64enc_0.1.3   callr_3.7.0       cli_3.2.0        
#>   clipr_0.8.0       compiler_4.1.2    crayon_1.5.0      digest_0.6.29    
#>   ellipsis_0.3.2    evaluate_0.15     fansi_1.0.2       fastmap_1.1.0    
#>   fs_1.5.2          glue_1.6.2        graphics_4.1.2    grDevices_4.1.2  
#>   highr_0.9         htmltools_0.5.2   jquerylib_0.1.4   jsonlite_1.8.0   
#>   knitr_1.37        lifecycle_1.0.1   magrittr_2.0.2    methods_4.1.2    
#>   pillar_1.7.0      pkgconfig_2.0.3   processx_3.5.2    ps_1.6.0         
#>   purrr_0.3.4       R.cache_0.15.0    R.methodsS3_1.8.1 R.oo_1.24.0      
#>   R.utils_2.11.0    R6_2.5.1          rematch2_2.1.2    reprex_2.0.1     
#>   rlang_1.0.1       rmarkdown_2.11    rprojroot_2.0.2   rstudioapi_0.13  
#>   stats_4.1.2       stringi_1.7.6     stringr_1.4.0     styler_1.6.2     
#>   tibble_3.1.6      tinytex_0.37      tools_4.1.2       utf8_1.2.2       
#>   utils_4.1.2       vctrs_0.3.8       withr_2.4.3       xfun_0.29        
#>   yaml_2.3.5

<sup>Created on 2023-02-20 by the reprex package (v2.0.1)</sup>

已解决,感谢 @yufree 的帮助!

其实产生这个问题的主要原因是字符编码问题。Ubuntu 下 R 的 unzip() 默认使用 “UTF-8”,并且没有提供修改为"CP936"的参数设置,所以只能放弃这个函数了,转而使用 system2() 调用系统的 unzip 命令。代码如下:

system2("unzip", c("-O", "CP936", "your_zip_file.zip", "-d", "your_output_directory"))

额,其实是我问的ChatGPT,我自己也没记住system2的用法,类似的我也写不出很严谨的正则表达式,不过现在似乎也没必要记了,还是让机器生成机器语言吧,这样使用者只要理解些低代码开发的概念就可以应对大多数数据分析场景了。