bounty还有4天到期。回答此问题可获得+50声望奖励。jc2525正在寻找一个答案从一个有信誉的来源。
就像标题说的那样。..我如何将代码嵌入到我的脚本中,将文件夹中的所有文件从utf16更改为utf8,以使R更容易阅读?
afdcj2ne1#
utf-16
R能够读取utf-16文件,因此可能不需要转换它们。但是,如果你想转换它们,这里是:1.一个R方法,用于将目录中的所有utf-16编码文件复制到一个新的utf-8编码文件夹中。这需要一次将每个文件读入RAM,这对于大文件可能会有问题。1.更改文件目录编码的本机操作系统方法列表(Linux/Mac和Windows):
utf-8
iconv
Get-Content
base
data.table
tidyverse
你可以写一个R函数,在utf-16中读入一个文件,然后在utf-8中写出:
convert_file_to_utf8 <- function(in_file, out_file, encoding = "utf-16") { in_file_conn <- file(in_file, encoding = encoding) txt <- readLines(in_file_conn) close(in_file_conn) # Create out directory if (!dir.exists(dirname(out_file))) dir.create(dirname(out_file)) # Write file with new encoding out_file_conn <- file(out_file, encoding = "utf-8") writeLines(txt, out_file_conn) close(out_file_conn) }
如果你想对整个目录执行此操作,那么你可以编写另一个函数来调用此函数:
create_utf8_dir <- function(in_dir = "./utf16dir/", out_dir = "./utf8dir/") { files <- dir(in_dir, full.names = TRUE) for (in_file in files) { out_file <- sub(in_dir, out_dir, in_file, fixed = TRUE) convert_file_to_utf8(in_file, out_file) } }
运行create_utf8_dir()将把"./utf16dir/"目录的utf-16编码内容复制到名为"./utf8dir/"的目录(如果不存在,将创建该目录)。
create_utf8_dir()
"./utf16dir/"
"./utf8dir/"
但是,如果文件很大,那么一次读取每个完整文件的R方法可能会使用大量的RAM。
如果你使用Linux/Mac,我会使用iconv,它可以change a file encoding while streaming the file,i。e.从不将整个文件内容保存在RAM中。对于一个文件,您可以执行以下操作:
iconv -f UTF-16 -t UTF-8 mtcars.csv > mtcars_utf8.csv
要复制R代码的行为,您可以执行以下操作:
IN_ENCODING=UTF16 OUT_ENCODING=UTF8 OUT_DIR=utf8dir for f in ./utf16dir/*; do basename="$(basename ${f%.*})" extension=${f##*.} outfile="./$OUT_DIR/$basename$OUT_ENCODING.$extension" echo $outfile iconv -f $IN_ENCODING -t $OUT_ENCODING $f > $outfile done
如果您使用的是Windows,则可以使用以下模式:
(Get-Content -path mtcars.csv) | Set-Content -Encoding ASCII -Path mtcarsutf8.csv
PowerShell中R和bash脚本的等价形式是:
$in_dir = "./utf16dir/" $out_dir = "./utf8dir/" If (!(test-path -PathType container $out_dir)) { New-Item -ItemType Directory -Path $out_dir } Get-ChildItem $in_dir | Foreach-Object { $outfile = $out_dir + $_.BaseName + "_utf8" + $_.Extension Write-Output $outfile (Get-Content -path $_.FullName) | Set-Content -Encoding ASCII -Path $outfile }
这将再次将目录"./utf16dir/"的utf-16编码内容复制到名为"./utf8dir/"的目录(如果不存在,它将创建该目录),并将"_utf8"附加到文件名。这种方法存在缺点:1.我将编码设置为ASCII,它是utf-8的子集。这里没问题,因为我知道所有的字符都是ASCII字符。如果不是这样,您可以将ASCII更改为UTF-8。但是,Windows使用utf-8-bom。删除字节顺序标记(BOM)并不完全简单-如果您有非ASCII字符,请参阅here。1.这就像R方法一样,一次将整个文件读入RAM。
"_utf8"
ASCII
UTF-8
utf-8-bom
您可以通过使用C#within Powershell逐行读取utf-16编码的文件,然后写出utf-8文件来克服这两个限制:
$code = @" using System; using System.IO; namespace ProcessLargeFile { public class Program { static void ConvertLine(string line, StreamWriter sw) { sw.WriteLine(line); } public static void ConvertFile(string path, string inDir, string outDir) { StreamReader sr = new StreamReader(File.Open(path, FileMode.Open)); string outPath = path.Replace(inDir, outDir); Console.WriteLine(outPath); StreamWriter sw = new StreamWriter(File.Open(outPath, System.IO.FileMode.Append)); try { while (!sr.EndOfStream){ string line = sr.ReadLine(); ConvertLine(line, sw); } } finally { sr.Close(); sw.Close(); } } static void ConvertDir(string inDir, string outDir) { string[] filePaths = Directory.GetFiles(inDir); Directory.CreateDirectory(outDir); foreach(string file in filePaths) { ConvertFile(file, inDir, outDir); } } public static void Main(string[] args){ string inDir = args[0]; string outDir = args[1]; ConvertDir(inDir, outDir); } } } "@ Add-Type -TypeDefinition $code -Language CSharp [ProcessLargeFile.Program]::Main(@("utf16dir/", "utf8dir/"))
这再次将"utf16dir/"的内容复制到"utf8dir/"。您可以通过更改最后一行中的参数来更改输入和输出目录。这种方法对文件进行流式处理并写出纯utf-8(没有BOM)。
"utf16dir/"
"utf8dir/"
在你的问题中,你说你希望改变编码,以使R更容易读取文件。如您所见,R能够读取utf-16文件,只要您在创建与file()的文件连接时指定编码即可。我将在这里介绍如何使用base R和流行的替代方案读取utf-16 csv文件。例如,假设您正在尝试读取以下文件:
file()
in_file <- "./utf16dir/mtcars.csv"
in_file_conn <- file(in_file, encoding = encoding) read.csv(text = readLines(in_file_conn))
in_file_conn <- file(in_file, encoding = encoding) data.table::fread( text = readLines(in_file_conn) )
readr::read_csv( in_file, locale = readr::locale(encoding = "utf-16") )
根据您的最终目标,您可能只希望读入utf-16编码的文件,而不是复制目录中的所有文件。
1条答案
按热度按时间afdcj2ne1#
R可以读取
utf-16
文件R能够读取
utf-16
文件,因此可能不需要转换它们。但是,如果你想转换它们,这里是:1.一个R方法,用于将目录中的所有
utf-16
编码文件复制到一个新的utf-8
编码文件夹中。这需要一次将每个文件读入RAM,这对于大文件可能会有问题。1.更改文件目录编码的本机操作系统方法列表(Linux/Mac和Windows):
iconv
转换文件流,即。e.避免将整个文件一次存储在存储器中。Get-Content
,它一次读取整个文件。1.如何使用
base
R、data.table
和tidyverse
将utf-16
csv文件读入R的摘要。如果你只是想把一些文件读入R,就没有必要复制它们的utf-8
编码,这可能是正确的方法。1. R函数更改文件编码
你可以写一个R函数,在
utf-16
中读入一个文件,然后在utf-8
中写出:如果你想对整个目录执行此操作,那么你可以编写另一个函数来调用此函数:
运行
create_utf8_dir()
将把"./utf16dir/"
目录的utf-16
编码内容复制到名为"./utf8dir/"
的目录(如果不存在,将创建该目录)。2.本机操作系统更改文件编码的方法
但是,如果文件很大,那么一次读取每个完整文件的R方法可能会使用大量的RAM。
2.1 bash
如果你使用Linux/Mac,我会使用
iconv
,它可以change a file encoding while streaming the file,i。e.从不将整个文件内容保存在RAM中。对于一个文件,您可以执行以下操作:要复制R代码的行为,您可以执行以下操作:
2.2 PowerShell
2.2.1纯PowerShell
如果您使用的是Windows,则可以使用以下模式:
PowerShell中R和bash脚本的等价形式是:
这将再次将目录
"./utf16dir/"
的utf-16
编码内容复制到名为"./utf8dir/"
的目录(如果不存在,它将创建该目录),并将"_utf8"
附加到文件名。这种方法存在缺点:
1.我将编码设置为ASCII,它是
utf-8
的子集。这里没问题,因为我知道所有的字符都是ASCII字符。如果不是这样,您可以将ASCII
更改为UTF-8
。但是,Windows使用utf-8-bom
。删除字节顺序标记(BOM)并不完全简单-如果您有非ASCII字符,请参阅here。1.这就像R方法一样,一次将整个文件读入RAM。
2.2.2 Powershell内嵌C#
您可以通过使用C#within Powershell逐行读取
utf-16
编码的文件,然后写出utf-8
文件来克服这两个限制:这再次将
"utf16dir/"
的内容复制到"utf8dir/"
。您可以通过更改最后一行中的参数来更改输入和输出目录。这种方法对文件进行流式处理并写出纯utf-8
(没有BOM)。3. base R,data.table和tidyverse方法来读取utf-16文件
在你的问题中,你说你希望改变编码,以使R更容易读取文件。如您所见,R能够读取
utf-16
文件,只要您在创建与file()
的文件连接时指定编码即可。我将在这里介绍如何使用base R和流行的替代方案读取utf-16
csv文件。例如,假设您正在尝试读取以下文件:base R
data.table
读取
根据您的最终目标,您可能只希望读入
utf-16
编码的文件,而不是复制目录中的所有文件。