Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 19-09-2016
Ramsay Ramsay is offline
Miembro
NULL
 
Registrado: ene 2016
Posts: 104
Poder: 9
Ramsay Va por buen camino
Dividir archivos en un TFileStream

Hola , tengo este codigo :

Código Delphi [-]
var
  InStream, OutStream: TFileStream;
....
OutStream := TFileStream.Create(OutFileName, fmCreate);
try
  InStream := TFileStream.Create(InFileName1, fmOpenRead);
  try
    OutStream.CopyFrom(InStream, InStream.Size);
  finally
    InStream.Free;
  end;
  InStream := TFileStream.Create(InFileName2, fmOpenRead);
  try
    OutStream.CopyFrom(InStream, InStream.Size);
  finally
    InStream.Free;
  end;
finally
  OutStream.Free;
end;

Sirve para unir dos archivos en uno solo , queria saber como podia dividir el archivo final con los dos archivos para tener acceso al segundo archivo usado en la union , ¿ alguien conoce como hacerlo ?
Responder Con Cita
  #2  
Antiguo 20-09-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
En un caso general, no queda una "marca" que divida los dos archivos. Sin embargo, si conoces el tamaño del primero, podrías usar el método Seek del Stream para colocar el puntero al principio de lo que sería el segundo archivo y a partir de ahí copiar a otro Stream.

LineComment Saludos
Responder Con Cita
  #3  
Antiguo 20-09-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Tal como te comenta roman, si previamente no agregas una marca, vas a tener que enviar los nombres y tamaños de los archivos (bytes) a extraer, por ejemplo:
Código Delphi [-]
procedure ExtractFiles(const SourceName: string; const TargetNames: array of string;
  const SizeTargets: array of Integer);
var
  Source, Target: TStream;
  Buffer: array of Byte;
  i : Integer;
begin
  Source := TFileStream.Create(SourceName, fmOpenRead);
  try
    for i := Low(TargetNames) to High(TargetNames) do
    begin
      Target := TFileStream.Create(TargetNames[i], fmCreate);
      try
        SetLength(Buffer, SizeTargets[i]);
        Source.ReadBuffer(Pointer(Buffer)^, Length(Buffer));
        Target.WriteBuffer(Buffer[0], Length(Buffer));
      finally
        Target.Free;
      end;
    end;
  finally
    Source.Free;
  end;
end;

Llamada ejemplo:
Código Delphi [-]
 ExtractFiles('concatenacion.txt', ['a1.txt', 'a2.txt', 'a3.txt'], [204, 192, 327 {bytes}]);

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 20-09-2016
Ramsay Ramsay is offline
Miembro
NULL
 
Registrado: ene 2016
Posts: 104
Poder: 9
Ramsay Va por buen camino
hola , gracias por la ayuda a los dos , efcisa , una pregunta , el tamaño de los archivos en bytes seria lo mismo que "InStream.Size" , ¿ verdad ?
Responder Con Cita
  #5  
Antiguo 20-09-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola
Cita:
Empezado por Ramsay Ver Mensaje
.. una pregunta , el tamaño de los archivos en bytes seria lo mismo que "InStream.Size" , ¿ verdad ?
El tamaño es el que tiene cada archivo previo a la concatenación.

Deberías obtener y guardar esos valores de tamaño en algún sitio, por que desde el archivo compuesto, es imposible obtener los tamaños de los diferentes archivos agregados.

De otro modo, habría que poner marcas para poder identificar la finalización de cada archivo.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 20-09-2016
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por ecfisa Ver Mensaje
Hola

El tamaño es el que tiene cada archivo previo a la concatenación.

Deberías obtener y guardar esos valores de tamaño en algún sitio, por que desde el archivo compuesto, es imposible obtener los tamaños de los diferentes archivos agregados.

De otro modo, habría que poner marcas para poder identificar la finalización de cada archivo.

Saludos
O bien armar una especie de Header a modo tabla que contenga la cantidad de items/archivos y sus respectivos tamaños. Luego es cosa de posicionarse en el lugar correcto y leer buffers de sus respectivos tamaños. Naturalmente este Header debe ser lo primero del archivo del archivo.

El header debe contener en este orden:
0.Cantidad de archivos
1. Tamaño del archivo #1
2. Tamaño del archivo #2
...
N. Tamaño del archivo #N

Luego viene la data del primer archivo, etc.

Lo que debe de cuidarse es de leer la cantidad justa de bytes. Por eso debe definirse adecuadamente que tipo de dato se va a usar para almacenar esta información... ¿Cuántos archivos se tiene pensado poder concatenar? Para 255 solo es suficiente con leer un byte... pero si se necesita de más se debe usar un SmallInt por lo menos.
Luego debe cuidarse también el tamaño de los archivos... Al menos las funciones que tiene Delphi y que actúan de indirección hacia la API de Windows, devuelven un Int64... ahí ya tienes unos cuantos bytes más por leer

Asi que de pronto, mínimo necesitas:
1. Leer el primer byte para saber la cantidad de archivos // si vas a permitir más de 255 necesitas 2 o más bytes... tu pones el límite!
2. Leer los siguientes 8 bytes para saber el tamaño del archivo
3. Ir a la posición correspondiente y leer el buffer de ese mismo tamaño
4. Repetir 2-4 según cantidad de archivos

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #7  
Antiguo 20-09-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
O bien armar una especie de Header a modo tabla que contenga la cantidad de items/archivos y sus respectivos tamaños. Luego es cosa de posicionarse en el lugar correcto y leer buffers de sus respectivos tamaños. Naturalmente este Header debe ser lo primero del archivo del archivo.
Exacto. Y tener así un archivo estructurado. El caso es que habría que saber qué es lo que se pretende al unir y desunir archivos y quizá entonces se pueda proponer una solución más ad hoc.

LineComment Saludos
Responder Con Cita
  #8  
Antiguo 20-09-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.039
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Así llegamos a la firma de Neftali: Si quieres obtener mejores respuestas, haz mejores preguntas.
O algo así
Responder Con Cita
  #9  
Antiguo 21-09-2016
Ramsay Ramsay is offline
Miembro
NULL
 
Registrado: ene 2016
Posts: 104
Poder: 9
Ramsay Va por buen camino
Hola ecfisa gracias por la ayuda , tu codigo funciona perfecto para cuando junto un ejecutable con otro archivo y luego los desuno , se descomprime bien pero cuando ejecuto el ejecutable desunido se muestra :

Cita:
Windows no puede encontrar el archivo "la ruta..." , Asegurese que el nombre este escrito correctamente e intetelo de nuevo
o

Cita:
La version de este archivo no es compatible con la version de windows que esta ejecutando ... (y despues habla de 32 o 64 bits)
Eh comprobado los size de los archivos y estan perfectos , ¿ conoces alguna solucion para corregir este problema ?

Última edición por Ramsay fecha: 21-09-2016 a las 15:43:26.
Responder Con Cita
  #10  
Antiguo 22-09-2016
Ramsay Ramsay is offline
Miembro
NULL
 
Registrado: ene 2016
Posts: 104
Poder: 9
Ramsay Va por buen camino
Estoy tratando de desunir con este codigo (intente con el tuyo pero intente solucionar el problema yo mismo y falle ...) :

Código Delphi [-]
var
  Source, Target: TStream;
  SourceName, TargetName: string;
  Size: Int64;
begin
  SourceName := 'salida.out';
  TargetName := 'programa.exe';

  Source := TFileStream.Create(SourceName, fmOpenRead);
  try
    Source.ReadBuffer(Size, SizeOf(Size));
    Source.Seek(2232832, 10751); // Bytes de los programas

    Source.ReadBuffer(Size, SizeOf(Size));

    Target := TFileStream.Create(TargetName, fmCreate);
    try
      Target.CopyFrom(Source, Size);
    finally
      Target.Free;
    end;
  finally
    Source.Free;
  end;
end;

En el codigo estoy tratando de guardar solo el segundo programa pero el ide me devuelve "stream read error" , en el codigo leo a partir del primer archivo para poder leer el segundo programa , ¿ como se soluciona ?
Responder Con Cita
  #11  
Antiguo 22-09-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Ramsay
Cita:
Empezado por Ramsay Ver Mensaje
Hola ecfisa gracias por la ayuda , tu codigo funciona perfecto para cuando junto un ejecutable con otro archivo y luego los desuno , se descomprime bien pero cuando ejecuto el ejecutable desunido se muestra :
Cita:
Windows no puede encontrar el archivo "la ruta..." , Asegurese que el nombre este escrito correctamente e intetelo de nuevo
o
Cita:
La version de este archivo no es compatible con la version de windows que esta ejecutando ... (y despues habla de 32 o 64 bits)
Eh comprobado los size de los archivos y estan perfectos , ¿ conoces alguna solucion para corregir este problema ?
Acabo de hacer la prueba (bajo Windows 32 bits) uniendo y extrayendo un archivo ejecutable con uno de texto sin ningún problema usando este código:
Código Delphi [-]
procedure ConcatFiles(const SourceNames: array of string; const TargetName: string);
var
  Source, Target: TFileStream;
  i : Integer;
begin
  if Length(SourceNames) < 1 then
    raise Exception.Create('Se requieren dos archivos al menos');
  Target := TFileStream.Create(TargetName, fmCreate);
  try
    for i := Low(SourceNames) to High(SourceNames) do
    begin
      Source := TFileStream.Create(SourceNames[i], fmOpenRead);
      try
        Target.CopyFrom(Source, Source.Size);
      finally
        Source.Free;
      end;
    end;
  finally
    target.Free;
  end;
end;

procedure ExtractFiles(const SourceName: string; const TargetNames: array of string;
  const SizeTargets: array of Integer);
var
  Source, Target: TStream;
  Buffer: array of Byte;
  i : Integer;
begin
  Source := TFileStream.Create(SourceName, fmOpenRead);
  try
    for i := Low(TargetNames) to High(TargetNames) do
    begin
      Target := TFileStream.Create(TargetNames[i], fmCreate);
      try
        SetLength(Buffer, SizeTargets[i]);
        Source.ReadBuffer(Pointer(Buffer)^, Length(Buffer));
        Target.WriteBuffer(Buffer[0], Length(Buffer));
        Form1.Memo1.Lines.Add(PChar(Buffer));
      finally
        Target.Free;
      end;
    end;
  finally
    Source.Free;
  end;
end;
El ejecutable funciona sin problema luego de ser extraido y el archivo de texto mantiene su contenido original.

En cuanto a los errores que comentas, el primero da toda la impresión que está provocado por un error al escribir alguna ruta o nombre de archivo.

Si bien el segundo mensaje advierte sobre alguna incompatibilidad de S.O., es muy probable que se produzca por enviar a la rutina de extracción un tamaño de archivo erróneo.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #12  
Antiguo 22-09-2016
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Al estar involucrados diferentes bitness debe cuidarse bien los tipos de enteros elejidos...
Pasar de 32bits a 64bits tiene sus cosas.
No es lo mismo hacer un SizeOf(mivariable) siendo mivariable un tipo entero NativeInt en 32bits que en 64bits. En 32 son 4 bytes, en 64bits es el doble.
No descartaría que sea un error de mal pasado los parámetros como sugiere Ecfisa, pero yo miraría más allá.

Y también hay que tener mucho cuidado con los archivos cuando se trabajan con equipos de diferentes endianness y se estará intercambiando entre ellos. Lo que se suele estilar es escribir en un endian prefijado y hacer la conversión de ser necesario. Lazarus está bien preparado en esto, ya tiene las funciones LEToN y BEToN para convertir Little Endian y Big Endian al tipo Nativo, como su contraparte NToLE y NtoBE. Delphi no las tiene... o al menos no se las encontré yo.
Si bien es cierto que la enorme mayoría de las PC son LE, hoy de moda está usar los celulares y estos son ¡en su mayoría BE!

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Agregar archivos en un TFileStream Ramsay Varios 4 19-09-2016 21:31:36
Ayuda con archivos binarios usando TFileStream Eze32 OOP 2 04-06-2013 16:18:07
Manejo de Archivos con TFileStream nlsgarcia Varios 6 02-09-2011 02:26:36
Uso de TFileStream esocrates Varios 4 09-04-2005 23:47:17
¿Como dividir un archivo en varios archivos? Raisen Varios 3 24-07-2004 03:16:28


La franja horaria es GMT +2. Ahora son las 12:01:14.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi