El siguiente comando de Powershell no puede copiar todo el archivo; siempre faltan algunos personajes al final.
[System.IO.StreamWriter]::new('C:\TEMP\b.csv', [System.Text.Encoding]::UTF8).Write([System.IO.StreamReader]::new('C:\Temp\a.csv', [System.Text.Encoding]::GetEncoding('iso-8859-1')).ReadToEnd())Sospecho que es porque el escritor no vacía los últimos bits porque esto copia todo el archivo:
$X = [System.IO.StreamReader]::new('C:\Temp\a.csv', [System.Text.Encoding]::GetEncoding('iso-8859-1')) $Y = [System.IO.StreamWriter]::new('C:\TEMP\b.csv', [System.Text.Encoding]::UTF8) $Y.Write($X.ReadAll()) $X.Dispose() $Y.Dispose()¿Es posible deshacerse de (y vaciar) el lector y el escritor sin haber creado variables para hacer referencia a ellos?
EDITAR: probé este one-liner usando streamreader/writer con la esperanza de que el búfer de lectura del lector se transfiriera directamente al búfer de escritura del escritor en lugar de esperar a que el lector leyera el archivo completo en la memoria y luego escribiera. ¿Qué técnica podría lograr eso?
Personalmente, encuentro que el código que no declara un objeto de un solo uso suele ser más limpio/más sucinto, pero mi atención se centra en comprender si los objetos se desechan a sí mismos y cómo, no el estilo.
No hay necesidad de evitar variables o escribir en una línea, pero este comportamiento no es lo que esperaba. En VBA, uno puede copiar un archivo como ese y confiar en que se deshará de sí mismo correctamente sin tener que declarar una variable y vaciar explícitamente (creo).
Sub Cpy() With New Scripting.FileSystemObject .CreateTextFile("c:\Temp\Out.txt").Write .OpenTextFile("C:\Temp\In.txt", ForReading).ReadAll End With End Sub Se puede lograr un comportamiento similar en una clase de VBA personalizada escribiendo el código de 'limpieza' apropiado en un procedimiento Class_Terminate() . Supuse que Streamwriter eliminaría los datos de manera similar al finalizar a través de la recolección de elementos no utilizados una vez que se ejecuta la línea y ya no hay una variable asociada con ella.
También noté que el archivo permanece bloqueado y no puedo eliminarlo hasta que cierre la sesión de PowerShell. ¿Hay alguna forma de vaciar el contenido y liberar el archivo sin haber declarado una variable con la que trabajar?
Solo para mostrarle que esto es posible y más fácil de hacer, usando los métodos estáticos de System.IO.File , WriteAllText() y ReadAllText() .
Lo siguiente consulta la API https://loripsum.net/ para obtener párrafos aleatorios y escribe en un archivo usando la codificación iso-8859-1 . Luego lee esos archivos y escribe una copia usando la misma codificación y, por último, compara los hashes de ambos archivos. Como puede ver, leer y escribir se hace todo como una sola línea.
Las declaraciones de using se pueden eliminar, pero deberá usar los nombres de tipo completo.
Establezca la ubicación en una carpeta temporal para realizar pruebas.
using namespace System.IO using namespace System.Text $fileRead = [Path]::Combine($pwd.Path, 'test.txt') $fileWrite = [Path]::Combine($pwd.Path, 'test-copy.txt') $loremIpsum = Invoke-RestMethod 'https://loripsum.net/api/5/short/headers/plaintext' [File]::WriteAllText($fileWrite, $loremIpsum, [Encoding]::GetEncoding('iso-8859-1')) [File]::WriteAllText( $fileWrite, [File]::ReadAllText($fileRead, [Encoding]::GetEncoding('iso-8859-1')), [Encoding]::GetEncoding('iso-8859-1') ) (Get-FileHash $fileRead).Hash -eq (Get-FileHash $fileWrite).Hash # => Should be True