Buenas tardes,
Me colaboraron con un PowerShell que lee un archivo CSV y transfiere a otro archivo CSV las columnas que yo elija, hasta aquí todo bien, funciona con archivos pequeños y de pocos registros, sin embargo estoy intentando cargar un archivo que pesa cerca de 1.5 Gb y según
Get-Content miarchivo.csv | Measure-Object
Count : 2563236
La cuestion es que según yo al cargar el archivo se queda sin memoria, se recibe el error: "Import-Csv : Exception of type 'System.OutOfMemoryException' was thrown"
algo para superar este inconveniente?
Cita de: Pisangas en 21 Diciembre 2017, 20:04 PMalgo para superar este inconveniente?
Prueba con las clases de
.NET Framework (esto tecnicamente ya no sería puto código
PowerShell):
script.ps1$lines = [System.IO.File]::ReadLines( "C:\File.csv", [System.Text.Encoding]::Default )
[System.Int32] $count = ($lines).Count
Write-Host $count
No estoy muy seguro de si funcionará. Por un lado la clase
IEnumerable (la cual es parecida a un
Array en la programación) es un tipo de evaluación vaga (
Lazy Evaluarion Type), esto quiere decir que las lineas del contenido del archivo.csv (o dicho de otra forma, los elementos del Array) solo se cargarán en memoria a medida que vaya siendo realmente necesario y se deasignará de la memoria cuando ya no sea necesario, por lo que en principio no sufririas un desbordamiento de memoria, sin embargo al usar la propiedad
IEnumerable.Count tiene que iterar todos los elementos de la colección
IEnumerable para hacer el conteo... así que no estoy seguro de lo que sucederá, pruébalo y me dices.
Saludos.
Method invocation failed because [System.IO.File] doesn't contain a method named 'ReadLines'.
At line:2 char:37
Lo estoy haciendo sobre el PowerShell, es correcto?
Cita de: Pisangas en 21 Diciembre 2017, 22:09 PM
Lo estoy haciendo sobre el PowerShell, es correcto?
si.
Cita de: Pisangas en 21 Diciembre 2017, 22:09 PM
por el momento me dice Method invocation failed because [System.IO.File] doesn't contain a method named 'ReadLines'.
Sin embargo validando la clase ReadLines si pertenece al objeto System.IO.File
La función
System.IO.File.ReadLines() fue introducida en la versión 4.0 de .NET Framework, así que necesitas tener instalada esa versión (como mínimo) o una superior en tu Windows. Si eso no es posible, entonces mo podrás usar ese código. Puedes probar con la función "ReadAllLines" en vez de "ReadLines" (solo tienes que cambiarle el nombre a esa parte del código), pero el resultado me temo que será muy distinto ( ya que esa función devuelve un Array como tal, así que probablemente se te desbordará la memoria, pero bueno, por probar... puedes intentarlo a ver. )
Saludos
Actualizo el .NET y te aviso cualquier cosa, gracias!
tengo la versión 4.7
Cita de: Eleкtro en 21 Diciembre 2017, 22:31 PM
si.
La función System.IO.File.ReadLines() fue introducida en la versión 4.0 de .NET Framework, así que necesitas tener instalada esa versión (como mínimo) o una superior en tu Windows. Si eso no es posible, entonces mo podrás usar ese código. Puedes probar con la función "ReadAllLines" en vez de "ReadLines" (solo tienes que cambiarle el nombre a esa parte del código), pero el resultado me temo que será muy distinto ( ya que esa función devuelve un Array como tal, así que probablemente se te desbordará la memoria, pero bueno, por probar... puedes intentarlo a ver. )
Saludos
Me temo que ocurre igual
Exception calling "ReadAllLines" with "1" argument(s): "Exception of type 'System.OutOfMemoryException' was thrown."
Cita de: Pisangas en 21 Diciembre 2017, 23:03 PM
Me temo que ocurre igual
Exception calling "ReadAllLines" with "1" argument(s): "Exception of type 'System.OutOfMemoryException' was thrown."
Eso te dije, que probablemente te ocurriría igual con "ReadAllLines". Prueba con "ReadLines", si tienes .NET Framework 4.7 deberías poder usar esa función, si te sale algún error, muestra el mensaje de error.
saludos
No se, responde igual
Method invocation failed because [System.IO.File] doesn't contain a method named 'ReadLines'.
At line:1 char:37
+ $lines = [System.IO.File]::ReadLines <<<< ( "C:\xxxx.csv", [System.Text.Encoding]::Default )
+ CategoryInfo : InvalidOperation: (ReadLines:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
y cuando lo cambio por la clase ReadAllLines arroja excepcion de memoria al cargar el csv
Exception calling "ReadAllLines" with "2" argument(s): "Exception of type 'System.OutOfMemoryException' was thrown."
At line:1 char:40
existe alguna manera de configurar en algún lugar un valor de memoria mas alto?
[MOD] usar "modificar" para añadir comentarios, no hacer doble post.
Bueno creo que de tanto buscar e intentar encontré la solución.
Como lo entendi, no era necesario esperar la importacion, luego la seleccion de las columnas para al final exportar, entonces por que no hacerlo todo al mismo tiempo
$csv = Import-Csv -Path "C:\xxx\xxx.csv" -Delimiter "|" | select "DATO1","DATO2","DATOn" | export-CSV C:\xxx\xxx.csv
tal vez sea una "chambonada"pero me funciono. Mil gracias por todo el apoyo.