可以在Powershell中构建一个动态的streamwriter数组吗?

时间:2013-02-08 14:18:37

标签: powershell streamreader streamwriter

我需要处理一个非常大的文件(> 10 GB)。因此我使用了StreamReaderStreamWriter。我的文件包含CSV格式的金融系列市场价格,如下所示:

Date,Time,Open,High,Low,Close,UpVol,DownVol

该文件包含多年的数据,我想每年创建一个文件,并删除最后两列。如果我将Year作为参数传递,我有一个脚本可以执行此操作。我想过多次调用这个脚本,但它必须多次读取非常大的文件。所以,我只想读取一次文件,并逐行将处理后的数据流式传输到不同的文件。这是我的单年剧本:

param ( 
    [String]$file=$(throw "Supply a file name to convert"),
    [String]$year
    );

$extension = [System.IO.Path]::GetExtension($file);
$outFile = $file.Substring(0, $file.LastIndexOf('.')) + "-" + $Year + $extension; 

$reader = [System.IO.File]::OpenText($file);
$writer = New-Object System.IO.StreamWriter $outFile;
$reader.ReadLine() > $null                          # skip first line (old header)
$writer.WriteLine("Date,Time,Open,High,Low,Close"); # write required header
while (($line = $reader.ReadLine()) -ne $null) {
    $data = $line.Split(",");
    if ($data[0] -match $year) {
        $writer.WriteLine($data[0] + "," + $data[1] + "," + $data[2] + "," + $data[3] + "," + $data[4] + "," + $data[5]);
    }
}
$reader.Close();
$writer.Close();

所以,我认为可以查看$ data [0](日期),找到这样的年份:

$thisYear = $data[0].Split("/")[2];

然后为找到的每年动态创建一个StreamWriter?我应该创建一个StreamWriters数组吗? Snag是,在我阅读之前,我不知道文件中有多少年或哪些年份。它必须“在飞行中”完成。如果我正在阅读的文件包含十年的数据,我预计会在最后创建十个额外的文件,并在其中包含相应年份的数据。

1 个答案:

答案 0 :(得分:1)

我建议使用哈希表来存储它们。然后你可以搜索一年找到你的编写者。尝试(未测试):

param ( 
    [String]$file=$(throw "Supply a file name to convert")
    )

$extension = [System.IO.Path]::GetExtension($file) 
$writers = @{}

$reader = [System.IO.File]::OpenText($file)
$reader.ReadLine() > $null                          # skip first line (old header)
while (($line = $reader.ReadLine()) -ne $null) {
    $data = $line.Split(",")
    $thisYear = $data[0].Split("/")[2]

    #If new year(no writer available)
    if (!$writers.ContainsKey($thisYear)) {
        #Create writer
        $outFile = $file.Substring(0, $file.LastIndexOf('.')) + "-" + $thisYear + $extension
        $writer = New-Object System.IO.StreamWriter $outFile
        $writer.WriteLine("Date,Time,Open,High,Low,Close")
        $writers.Add($thisYear, $writer)
    }

    $writers[$thisYear].WriteLine($data[0] + "," + $data[1] + "," + $data[2] + "," + $data[3] + "," + $data[4] + "," + $data[5])
}
$reader.Close()
$writers.GetEnumerator() | % { $_.Value.Close() }