Dudas sobre manejo de archivos
Facon
p0stm4n en gmail.com
Dom Jul 6 01:57:37 CEST 2008
Sorry, ya me lo solucionaron con un pequeño script que simplifica y
optimiza bastante mi código, además ahora pueden trocear con cualquier
tamaño:
# -*- coding: cp1252 -*-
# Cortador by Shrick
# Gracias a Google y Documentación de Python
# Agradecimientos a http://www.elhacker.net, en especial a Novlucker
import string
import os
import sys
ruta = sys.argv[1] # Archivo a dividir
nombre_archivo = os.path.basename(ruta) # Obtener nombre real del archivo
tamano_trozo = sys.argv[2] # Tamaño de los trozos (Bytes xDDDD)
destino = sys.argv[3] # Destino de los Trozos
destino2 = destino
tamano_trozo = int(tamano_trozo) # Pasamos argumento de String a Integer
tamano = os.path.getsize(ruta) # Tamaño del Archivo (Bytes)
print "\nTamaño: " + repr(tamano) + " Bytes\n\nParticionando Archivo,
por favor espere..." # Imprimir Tamaño del Archivo (Bytes)
datos = '' # Datos del buffer
posicion = 0 # Para posicionarse en los datos a leer
i = 0 # Para Hacer .0, .1, .2, .3, .4, etc...
wrote = 0
trozo = 0
megabyte = 1048576
f = open (ruta, 'rb') # Abrimos archivo
while wrote < tamano: # Creamos bucle que diga que si posicion menor o
igual que tamaño hago lo que esta a continuación
destino = destino + nombre_archivo + "." + repr(i) # Crear nombre
del archivo prueba.jpg.0, prueba.jpg.1, prueba.jpg.*
print "Creado: " + destino
trozo = 0
j = open (destino, 'ab') # Creamos el archivo prueba.jpg.*
while trozo<tamano_trozo:
datos = f.read (megabyte)
trozo = trozo + len(datos) # bucle infinito
j.write (datos)
if len(datos) == 0:
break
wrote = wrote + trozo
j.close()
i = i + 1
destino = destino2
f.close() # Cerramos archivo principal
x = open (destino2 + nombre_archivo + ".bat", 'w') # A partir de aquí
creamos el .bat para pegar archivos
x.write('copy /b "'+ nombre_archivo + '.0" "' + nombre_archivo + '"\n')
z = 1
while z<i:
x.write('copy /b "'+ nombre_archivo +'"+"'+ nombre_archivo +'.'+
repr(z)+ '"\n')
z = z + 1
x.close()
# x = open ('pegador_linux', 'w') # Creamos el equivalente .bat para
Linux es decir para Bash
# x.write('#!/bin/bash\n')
-- FIN CÓDIGO --
El día 5 de julio de 2008 23:12, Facon <p0stm4n en gmail.com> escribió:
> ¡Hola Comunidad!, soy nuevo aquí desde hace poco, y desde entonces he
> leído algunos digest, que se crean para los usuarios como resumen,
> algunos de los cuales me han resultado verdaderamente útiles para lo
> que estoy intentando desarrollar.
>
> De momento se poco de Python, pero poco a poco voy aprendiendo
> cositas, y si necesito algo suelo mirar la documentación o googlear,
> para encontrar una respuesta, sin embargo en esta ocasión estoy
> estantacado porque no se por donde tirar, estoy desarrollando un
> Cortador de Archivos que permita dividir un Archivo en varios trozos
> de tantos MBs, de forma que si por ejemplo tengo un archivo llamado
> "prueba.zip" de 3MB, el programa me crea: "prueba.zip.0",
> "prueba.zip.1" y "prueba.zip.2" de 1MB cada uno, hasta hay bien porque
> lo he conseguido, puedo trocear archivos de más de 6.69 GB (Es con el
> último archivo que probe).
>
> Mi problema consiste en que ha pesar de que puede con casi cualquier
> archivo en cuanto a tamaño se refiere, el problema es el tamaño de los
> trozos, que ha partir de 500 MB me da el error "Memory Error", debido
> a que es demasiado extenso los datos que añado al string, asi que
> decidi hacerlo por arrays (y me funciona), pero el problema es que
> para el último archivo con el seek(), tengo el problema de que cuando
> escribe en el último archivo, que me pone repetido.
>
> Funciona:
>
> $ python cortador.py archivo_origen tamaño destino
>
> El tamaño es en bytes.
>
> El código:
>
> cortador.py:
>
> # -*- coding: cp1252 -*-
> # Cortador by Facon
> # Gracias a Google y Documentación de Python
> # Agradecimientos a http://www.elhacker.net, en especial a Novlucker
>
> import string
> import os
> import sys
>
> ruta = sys.argv[1] # Archivo a dividir
> nombre_archivo = os.path.basename(ruta) # Obtener nombre real del archivo
> tamano_trozo = sys.argv[2] # Tamaño de los trozos (Bytes xDDDD)
> destino = sys.argv[3] # Destino de los Trozos
> destino2 = destino
> tamano_trozo = int(tamano_trozo) # Pasamos argumento de String a Integer
> tamano = os.path.getsize(ruta) # Tamaño del Archivo (Bytes)
> print "\nTamaño: " + repr(tamano) + " Bytes\n\nParticionando Archivo,
> por favor espere..." # Imprimir Tamaño del Archivo (Bytes)
> datos = ['', '', ''] # Datos del buffer
> posicion = 0 # Para posicionarse en los datos a leer
> i = 0 # Para Hacer .0, .1, .2, .3, .4, etc...
> f = open (ruta, 'rb') # Abrimos archivo
> while posicion <= tamano: # Creamos bucle que diga que si posicion
> menor o igual que tamaño hago lo que esta a continuación
> destino = destino + nombre_archivo + "." + repr(i) # Crear nombre
> del archivo prueba.jpg.0, prueba.jpg.1, prueba.jpg.*
> print "Creado: " + destino
> j = open (destino, 'ab') # Creamos el archivo prueba.jpg.*
> datos = ['', '', '']
> if tamano_trozo >= 419430400:
> if i == 0:
> datos[0] = f.read(tamano_trozo/3) # Datos toma lo leido del buffer
> f.seek(tamano_trozo/3)
> datos[1] = f.read (tamano_trozo/3) # Datos toma lo leido del buffer
> f.seek(tamano_trozo/3)
> datos[2] = f.read (tamano_trozo/3) # Datos toma lo leido del buffer
> f.seek(tamano_trozo/3)
> j.write(datos[0]) # Escribimos en el archivo.
> j.write(datos[1])
> j.write(datos[2])
> j.close() # Cerramos archivo
> posicion = tamano_trozo # Metemos la posición siguiente en
> la integer
> i = i + 1 # Sumamos 1 a la variable integer
> else:
> f.seek (posicion) # Función que va al byte con el valor de posición
> datos[0] = f.read(tamano_trozo/3) # Poner datos (X bytes
> de info.) en la variable desde esa posición
> f.seek(tamano_trozo/3)
> az = f.seek(tamano_trozo/3)
> datos[1] = f.read(tamano_trozo/3)
> f.seek(tamano_trozo/3)
> ad = f.seek(tamano_trozo/3)
> datos[2] = f.read(tamano_trozo/3)
> f.seek(tamano_trozo/3)
> if az == tamano or ad == tamano:
> datos[1] = ''
> datos[2] = ''
> j.write(datos[0]) # Escribimos en archivo
> j.write(datos[1])
> j.write(datos[2])
> posicion = posicion + tamano_trozo # Vamos una posicion más avanzada
> j.close() # Cerramos archivo
> i = i + 1 # Sumamos 1 a la variable integer
> else:
> if i == 0:
> datos[0] = f.read(tamano_trozo) # Datos toma lo leido del buffer
> j.write(datos[0]) # Escribimos en el archivo.
> j.close() # Cerramos archivo
> posicion = tamano_trozo # Metemos la posición siguiente en
> la integer
> i = i + 1 # Sumamos 1 a la variable integer
> else:
> f.seek (posicion) # Función que va al byte con el valor de posición
> datos[0] = f.read(tamano_trozo) # Poner datos (X bytes de
> info.) en la variable desde esa posición
> j.write(datos[0]) # Escribimos en archivo
> posicion = posicion + tamano_trozo # Vamos una posicion más avanzada
> j.close() # Cerramos archivo
> i = i + 1 # Sumamos 1 a la variable integer
> destino = destino2
> f.close() # Cerramos archivo principal
>
> x = open (destino2 + nombre_archivo + ".bat", 'w') # A partir de aquí
> creamos el .bat para pegar archivos
> x.write('copy /b "'+ nombre_archivo + '.0" "' + nombre_archivo + '"\n')
> z = 1
> while z<i:
> x.write('copy /b "'+ nombre_archivo +'"+"'+ nombre_archivo +'.'+
> repr(z)+ '"\n')
> z = z + 1
> x.close()
>
> # x = open ('pegador_linux', 'w') # Creamos el equivalente .bat para
> Linux es decir para Bash
> # x.write('#!/bin/bash\n')
>
> -- FIN CÓDIGO --
>
> Pueden copiar como quiera, lo puse en
> _http://code.google.com/p/pythonprogramas/ bajo GPL v3, para que hagan
> lo que quieran con el código.
>
> Por favor ayudenme!.
>
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es