Ir al contenido



Foto

Problema al leer un archivo


  • Por favor identifícate para responder
18 respuestas en este tema

#1 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 09 enero 2017 - 11:24

Hola  tengo un problema al tratar de leer un archivo q creo con datos obtenidos por UDP, esto es lo q contrine

LOOP get             ‰p 0k
k
†i‰iˆi111111111111111111111111
   ˆ N Underground MW3 ES 107 - ^224h gn\IW5\gt\koth\hc\0\pu\1\m\mp_underground\px\850\pn\\mr\\pc\0\ff\0\fg\\md\\kc\1\ac\0\d\1\qp\27017\vo\0\ \g_gametype\koth\g_hardcore\0\gamename\IW5\mapname\mp_underground\protocol\97\scr_game_allowkillcam\1\scr_team_fftype\0\shortversion\1.2\sv_allowClientConsole\0\sv_floodProtect\1\sv_hostname\MW3 ES 107 - ^224h\sv_maxclients\18\sv_privateClients\0\sv_privateClientsForClients\0\sv_pure\1\sv_voice\No Chat\pswrd\0\mod\0
0 39 "RAZOR"
0 69 "BAN"
0 39 "PESADILLA"
0 48 "AGUILA"
0 38 "[GXY]LACHY"
0 999 "CEBALLITO"
0 59 "R@NGER"
0 999 "YPACHECO"
0 69 "EDIER"
 

lo leo con esto


delphi
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var F: TextFile;
  3. sLinea: String;
  4. begin
  5. AssignFile( F, ExtractFilePath( Application.ExeName ) + 'temp' );
  6. Reset( F );
  7.  
  8. while not Eof( F ) do
  9. begin
  10. ReadLn( F, sLinea );
  11. Memo1.Lines.Add( sLinea );
  12. end;
  13.  
  14. CloseFile( F );
  15.  
  16. end;

 y me debuelbe

 

LOOP get
k
†i‰iˆi111111111111111111111111
0 39 "RAZOR"
0 69 "BAN"
0 39 "PESADILLA"
0 48 "AGUILA"
0 38 "[GXY]LACHY"
0 999 "CEBALLITO"
0 59 "R@NGER"
0 999 "YPACHECO"
0 69 "EDIER"
 

como ven se salta una pila de cosas, y hay una pila de carecteres estraño.

 

 


  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.395 mensajes
  • LocationMéxico

Escrito 09 enero 2017 - 11:38

Hola Dante
 
Yo veo dos alternativas para leer el archivo.
 
 
Una basada en tu código
 
 

delphi
  1. procedure TForm2.Button1Click(Sender: TObject);
  2. var
  3. F: TextFile;
  4. caracter: char;
  5. cadena: string;
  6. begin
  7.   AssignFile( F, ExtractFilePath( Application.ExeName ) + 'temp' );
  8.   Reset( F );
  9. cadena := '';
  10.   while not Eof( F ) do
  11.   begin
  12.     Read( F, caracter );
  13. cadena := cadena + caracter;
  14.   end;
  15.   Memo1.Lines.Text := cadena;
  16.   CloseFile( F );
  17. end;

 
Y la otra con menos código :)
 

delphi
  1. procedure TForm2.Button2Click(Sender: TObject);
  2. var
  3. archivo: TStrings;
  4. begin
  5.   archivo := TStringList.create;
  6.   archivo.LoadFromFile(ExtractFilePath( Application.ExeName ) + 'temp' );
  7.   Memo1.Lines := archivo;
  8. end;

 
Saludos
  • 0

#3 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 09 enero 2017 - 12:00

las dos formas me debuelben

 

LOOP get[] 

en ese punto es donde empesiasn caracteres estraños por eso la conversion de binari a string simpre se me detiene ahi

como podria eliminar eso caractres para poder leer el archivo completo


  • 0

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.001 mensajes
  • LocationRepública Dominicana

Escrito 09 enero 2017 - 12:09

Debes especificar que es lo que quieres te devuelva, veo una especie de ranking..
  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.775 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 12:10

No hay ningún error ni nada extraño en eso.

Lo que lees es justo lo que tiene el archivo.

 

Tu problema es que desconoces la estructura/diseño/formato del archivo. Pero insisto: lo que lees es lo que hay.

Es ya responsabilidad tuya en tratar la info leída apropiadamente.

 

Si desconoces como es que fue diseñado y su estructura no se puede hacer nada.

 

Saludos,


  • 1

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.395 mensajes
  • LocationMéxico

Escrito 09 enero 2017 - 12:24

las dos formas me debuelben
 
LOOP get[] 
en ese punto es donde empesiasn caracteres estraños por eso la conversion de binari a string simpre se me detiene ahi
como podria eliminar eso caractres para poder leer el archivo completo


Si subes el archivo podemos saber exactamente porque no se lee correctamente.

Saludos
  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.775 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 12:30

Si subes el archivo podemos saber exactamente porque no se lee correctamente.

Saludos

 

El archivo se lee correctamente amigo.

El problema está en que Dante desconoce la estructura o diseño del mismo.

¿Que se supone que debe ser la 1ra parte del contenido "indescifrable"? A menos que exista documentación libre sobre el formato no podremos saberlo, sólo el que diseñó el sistema original que generó ese archivo lo sabe.

Posiblemente los primeros bytes sean alguna especie de Cabecera o Header... y los siguientes parecerían ser un listado de directorios. La lista del final es lo más obvio por su "fácil lectura".

 

Saludos,


  • 0

#8 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 09 enero 2017 - 12:40

el archivo lo creo yo, es el resultado a una consulta q le ago a un programa por el protocolo UDP y el me devuelve el texto en binario con lo q creo el archivo este es el binario q me debuelbe:

 

4C4F4F5020676574 0700000012000000 0001000000010000 0089139D70010030
016B01010A6B0101 0A86698969886931 3131313131313131 3131313131313131
3131313131313101 000D00200088004E 0200556E64657267 726F756E64004D57
3320455320313037 202D205E32323468 00676E5C4957355C 67745C6B6F74685C
68635C305C70755C 315C6D5C6D705F75 6E64657267726F75 6E645C70785C3835
305C706E5C5C6D72 5C5C70635C305C66 665C305C66675C5C 6D645C5C6B635C31
5C61635C305C645C 315C71705C323730 31375C766F5C305C 005C675F67616D65
747970655C6B6F74 685C675F68617264 636F72655C305C67 616D656E616D655C
4957355C6D61706E 616D655C6D705F75 6E64657267726F75 6E645C70726F746F
636F6C5C39375C73 63725F67616D655F 616C6C6F776B696C 6C63616D5C315C73
63725F7465616D5F 6666747970655C30 5C73686F72747665 7273696F6E5C312E
325C73765F616C6C 6F77436C69656E74 436F6E736F6C655C 305C73765F666C6F
6F6450726F746563 745C315C73765F68 6F73746E616D655C 4D57332045532031
3037202D205E3232 34685C73765F6D61 78636C69656E7473 5C31385C73765F70
726976617465436C 69656E74735C305C 73765F7072697661 7465436C69656E74
73466F72436C6965 6E74735C305C7376 5F707572655C315C 73765F766F696365
5C4E6F2043686174 5C70737772645C30 5C6D6F645C300A30 203339202252415A
4F52220A30203639 202242414E220A30 2033392022504553 4144494C4C41220A
3020343820224147 55494C41220A3020 333820225B475859 5D4C41434859220A
3020393939202243 4542414C4C49544F 220A302035392022 52404E474552220A
3020393939202259 5041434845434F22 0A30203639202245 44494552220A0000

 

si trato de convertirlo a string me debuelve LOOP get[]

creando un archivo y escribiendolo en binario fue q pude obtener lo q posteo al principio


  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.775 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 12:54

Si tu generas el archivo, ¿Cómo es que lo grabas? Deberás brindar esa info.

Por otro lado, ¿Sabes si lo que te envia el otro programa (que al parecer es de terceros) por UDP es info limpia? Es decir, si lo que te devuelve es sólo el contenido DATA del formato UDP ¿O estás recibiendo todo el paquete?

¿Cómo es que le consultas? ¿Que componentes usas?

 

Recuerda que el protocolo UDP tiene un formato definido, y en los primeros bytes se maneja info relativa a Dirección de Origen, Destino, Puerto, Longittud del mensaje, etc. ¿No será que justamente el "contenido indescifrable" es justamente esto?

 

Pero insisto en mi punto. Esto no elimina del todo el mayor problema del fondo: si no sabes interpretar la DATA que te envía ese programa, de nada sirve que la guardes.

 

Saludos,


  • 0

#10 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 588 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 12:59

Obviamente que Marcelo tiene razon

 

La pregunta mas fundamental que tenes que responder es esto:

 

 

 

LOOP get             ‰p 0k
k
†i‰iˆi111111111111111111111111
   ˆ N Underground MW3 ES 107 - ^224h gn\IW5\gt\koth\hc\0\pu\1\m\mp_underground\px\850\pn\\mr\\pc\0\ff\0\fg\\md\\kc\1\ac\0\d\1\qp\27017\vo\0\ \g_gametype\koth\g_hardcore\0\gamename\IW5\mapname\mp_underground\protocol\97\scr_game_allowkillcam\1\scr_team_fftype\0\shortversion\1.2\sv_allowClientConsole\0\sv_floodProtect\1\sv_hostname\MW3 ES 107 - ^224h\sv_maxclients\18\sv_privateClients\0\sv_privateClientsForClients\0\sv_pure\1\sv_voice\No Chat\pswrd\0\mod\0
0 39 "RAZOR"
0 69 "BAN"
0 39 "PESADILLA"
0 48 "AGUILA"
0 38 "[GXY]LACHY"
0 999 "CEBALLITO"
0 59 "R@NGER"
0 999 "YPACHECO"
0 69 "EDIER"

 

Tenes esos "datos", los queres convertir, en "que"? Que esperas de ese archivo? Que estructura de datos queres crear?

 

Tenes que volver sobre tus pasos, a lo mas basico. Si yo te doy ese texto de entrada deberias poder convertirlo "a mano", "mentalmente" sin necesidad de un programa. Como vas a instruirle a una computadora que haga la conversion si ni siquiera vos sabes como hacerlo??


Editado por Agustin Ortu, 09 enero 2017 - 01:00 .

  • 0

#11 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.575 mensajes
  • LocationMadrid - España

Escrito 09 enero 2017 - 01:02

Hay un problema al convertir un archivo binario a texto. O te aseguras que el archivo creado es texto puro y duro o debes leerlo cómo binario, asimilarlo a una estructura (para separar las partes de texto y binario) y poder intrepretarlo.

 

Si usas clases o funciones basadas en Stings, tendrás errores de interpretación con un archivo que mezcla texto y binario. Éstos deben considerarse binario siempre pues caracteres como #0, #13, #10 y los no representables, te romperán el archivo.

 

Ahora no puedo probar tu archivo pero lo mejor es que lo subas cómo adjunto para que alguien pueda analizarlo.

 

 

Saludos. 


  • 0

#12 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 09 enero 2017 - 01:29

en completo lo q quierio y como e llegado a lo q tengo es :

tengo una aplicacion q se comunica con el server de un juego y extrae las estadisticas, esto lo hace por un puerto UDP.

yo quiero q mi aplicacion aga lo mismo por lo q monte un  servidor UDP al cual conecte la aplicaion q se copmunica con el servidor del juego y esta me envio esto "LOOP getstatus", luego creo un cliente UDP con indy10  y uso esto:


delphi
  1. procedure TForm1.IdUDPClient1Connected(Sender: TObject);
  2. var
  3. a:TIdBytes;
  4.  
  5. hFile: THANDLE;
  6. begin
  7. IdUDPClient1.Send('LOOP getstatus');
  8. SetLength(a,IdUDPClient1.BufferSize);
  9. IdUDPClient1.ReceiveBuffer(a,-1);
  10.  
  11. hFile:= CreateFile(pchar('temp'), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
  12. if hFile <> INVALID_HANDLE_VALUE then
  13. begin
  14. _lwrite(hFile, @a[0], Length(a));
  15. CloseHandle(hFile);
  16. end;
  17.  
  18. end;

y asi obtengo el fichero mensionado.

En el fichero se encuentra toda la informacion q nesisito.

Archivos adjuntos

  • Archivo adjunto  temp.rar   504bytes   2 descargas

  • 0

#13 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 588 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 03:24

En el fichero se encuentra toda la informacion que necesito.


Que informacion? Que tenes que hacer con ese archivo?
  • 0

#14 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 09 enero 2017 - 03:44

mira en esta linea se encuntra el nombre del sever, tipo de juego, nombre del mapa , maximo de clientes yotras cosas q por el moneto no me interesan

 

   ȠN Underground MW3 ES 107 - ^224h gn\IW5\gt\koth\hc\0\pu\1\m\mp_underground\px\850\pn\\mr\\pc\0\ff\0\fg\\md\\kc\1\ac\0\d\1\qp\27017\vo\0\ \g_gametype\koth\g_hardcore\0\gamename\IW5\mapname\mp_underground\protocol\97\scr_game_allowkillcam\1\scr_team_fftype\0\shortversion\1.2\sv_allowClientConsole\0\sv_floodProtect\1\sv_hostname\MW3 ES 107 - ^224h\sv_maxclients\18\sv_privateClients\0\sv_privateClientsForClients\0\sv_pure\1\sv_voice\No Chat\pswrd\0\mod\0

 

esto otro son en orden por columnas la puntuacion, ping , nombre del player

 

 

0 39 "RAZOR"
0 69 "BAN"
0 39 "PESADILLA"
0 48 "AGUILA"
0 38 "[GXY]LACHY"
0 999 "CEBALLITO"
0 59 "R@NGER"
0 999 "YPACHECO"
0 69 "EDIER"

 

 

esto es lo q me interesa de aki


  • 0

#15 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.575 mensajes
  • LocationMadrid - España

Escrito 09 enero 2017 - 06:20

En el offset 215h tienes 0 39 "RAZOR"+#10 y a partir de ese punto todos los nombres.

 

El tema es saber si la información previa a lo que te interesa ocupa siempre $215 bytes, para eso tendrás que leer varios archivos de esos y comprobarlo. En el que muestras no aparecen referencias a esa localización en la cabecera que es binaria.

 

Te muestro un código que extrae la información que quieres, suponiendo que siempre esté en el offset $0215:


delphi
  1. function LoadData(FileName: String): String;
  2. var
  3. Buffer: PBYTE;
  4. Size: integer;
  5. hFile: THANDLE;
  6. begin
  7. hFile:= CreateFile(PCHAR(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  8. if hFile <> INVALID_HANDLE_VALUE then
  9. begin
  10. Size:= GetFileSize(hFile, 0);
  11. Buffer:= GetMemory(Size);
  12. _lread(hFile, Buffer, Size);
  13. Result:= PAnsiChar(Buffer)+$215;
  14. CloseHandle(hFile);
  15. FreeMemory(Buffer);
  16. end;
  17. end;
  18.  
  19. procedure TForm1.Button1Click(Sender: TObject);
  20. begin
  21. Memo1.Lines.Delimiter:= #10;
  22. Memo1.Lines.DelimitedText:= LoadData('temp');
  23. end;

Saludos.


  • 0

#16 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.575 mensajes
  • LocationMadrid - España

Escrito 09 enero 2017 - 07:06

Otra forma de llegar a los nombres sería esta:


delphi
  1. function LoadData2(FileName: String): String;
  2. var
  3. Buffer: PBYTE;
  4. Size: integer;
  5. hFile: THANDLE;
  6. OffSet: integer;
  7. begin
  8. hFile:= CreateFile(PCHAR(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  9. if hFile <> INVALID_HANDLE_VALUE then
  10. begin
  11. Size:= GetFileSize(hFile, 0);
  12. Buffer:= GetMemory(Size);
  13. _lread(hFile, Buffer, Size);
  14. OffSet:= 0;
  15. while (PAnsiChar(Buffer)[OffSet] <> '"') and (OffSet < Size) do inc(OffSet);
  16. inc(OffSet, -5);
  17. Result:= PAnsiChar(Buffer) + OffSet;
  18. CloseHandle(hFile);
  19. FreeMemory(Buffer);
  20. end;
  21. end;

Saludos.


  • 0

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.775 mensajes
  • LocationArgentina

Escrito 09 enero 2017 - 07:08

La verdad es que no entiendo cual es el problema o dificultad. Si Dante realmente sabe distinguir lo que contiene esa línea (o esas líneas) que está "formateada" con barras invertidas, ¿que le impide "trozar" el contenido por partes y leer la indicada.

 

En lugar de asumir que esté en cierto offset, si efectivamente por ejemplo, el nombre del server está antes de la primera barra, y que por ejemplo el número máximo de server está en la 18va barra, basta con utilizar por ejemplo un StringList y establecer como delimitador de texto la barra invertida. Luego en cada línea tendrá la info "separada". Deberá posicionarse en la que desea y leerla.

 

Esto va a servir siempre que se compruebe que se respete ese "formato": el orden de los elementos y en cantidad.

 

Saludos,


  • 0

#18 Dante

Dante

    Advanced Member

  • Miembros
  • PipPipPip
  • 65 mensajes

Escrito 10 enero 2017 - 08:00

lo q me impedia trosear el contenido de el archivos era al tratr de converti el buffer a un string, me daba error porque hanbian carateres #0, lo q hice fue limpiar el buffer de estoy caracteres y ya no tuve ni q crear el archivo, asi fue como lo ise, quisas no sea lo mas practico y rapido pero es lo q se me ocurrio anoche


delphi
  1. procedure TForm2.getstat;
  2. var
  3. Buffr:TIdBytes;
  4. b,i,cont:integer;
  5. letra:char;
  6. e,map:string;
  7. item: TListItem;
  8. begin
  9.  
  10. IdUDPClient1.Port:=27017;
  11. IdUDPClient1.Host:=Edit1.Text;
  12. IdUDPClient1.Connect;
  13. IdUDPClient1.Send('LOOP getstatus');
  14. SetLength(Buffr,IdUDPClient1.BufferSize);
  15. b:=IdUDPClient1.ReceiveBuffer(Buffr,3000);
  16. SetLength(Buffr,b);
  17.  
  18. for i := b-1 downto 0 do
  19. begin
  20.  
  21. if (Buffr[I]<>0) and (Buffr[I]<>17)
  22. and (Buffr[I]<>18)and (Buffr[I]<>1)
  23. and (Buffr[I]<>27)and (Buffr[I]<>15)then
  24. begin
  25. if (Buffr[I]<>10) then
  26. begin
  27. letra := Chr(Buffr[I]);
  28. e := letra + e;
  29. end
  30. else e:='|'+e;
  31. end;
  32.  
  33.  
  34. end;
  35.  
  36. map:=GetToken(e,'\',43);
  37. if map='mp_alpha' then map:='Lockdown' else
  38. if map='mp_bootleg' then map:='Bootleg' else
  39. if map='mp_bravo' then map:= 'Mission' else
  40. if map='mp_carbon' then map:='Carbon' else
  41. if map='mp_dome' then map:='Dome' else
  42. if map='mp_exchange' then map:='Downturn' else
  43. if map='mp_hardhat' then map:='Hardhat' else
  44. if map='mp_paris' then map:='Resistance' else
  45. if map='mp_interchange' then map:='Interchange' else
  46. if map='mp_lambeth' then map:= 'Fallen' else
  47. if map='mp_plaza2' then map:='Arkaden' else
  48. if map='mp_underground' then map:='Underground' else
  49. if map='mp_lambeth' then map:='Fallen'else
  50. if map='mp_mogadishu' then map:='Bakaara' else
  51. if map='mp_radar' then map:='Outpost' else
  52. if map='mp_seatown' then map:='Seatown' else
  53. if map='mp_village' then map:='Village' else
  54. map:='random';
  55.  
  56.  
  57. Label2.Caption:='Nombre del mapa: '+ map;
  58. Image1.Picture.LoadFromFile(FilePath+'mapimages\'+map+'.gif');
  59. ListView1.Items.Clear;
  60. e:= GetToken(e,'\',71);
  61. for I := 2 to 22 do
  62. begin
  63. if trim(GetToken(e,'|',I))<> '' then
  64. begin
  65. item:= ListView1.Items.Add;
  66. item.Caption:= GetToken(GetToken(e,'|',I),' ',3);
  67. item.SubItems.Add(GetToken(GetToken(e,'|',I),' ',1));
  68. item.SubItems.Add(GetToken(GetToken(e,'|',I),' ',2));
  69. end
  70. else
  71. begin
  72. Label3.Caption:= 'Conectados: ' + ListView1.Items.Count.ToString + '/18';
  73. Break
  74.  
  75. end;
  76.  
  77. end;
  78.  
  79. if IdUDPClient1.Connected then
  80. IdUDPClient1.Disconnect;
  81.  
  82. end;

de todas maneras voy a provar lo q dijo escafandra, muchisimas grasias a todos los q me ayudaron


  • 0

#19 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.575 mensajes
  • LocationMadrid - España

Escrito 10 enero 2017 - 08:52

lo q me impedia trosear el contenido de el archivos era al tratr de converti el buffer a un string, me daba error porque hanbian carateres #0, lo q hice fue limpiar el buffer de estoy caracteres y ya no tuve ni q crear el archivo, asi fue como lo ise, quisas no sea lo mas practico y rapido pero es lo q se me ocurrio anoche
...
de todas maneras voy a provar lo q dijo escafandra, muchisimas grasias a todos los q me ayudaron

Como te comenté, ciertos valores de byte son interpretados al leerlos en modo texto y se corrompe la información. Lo suyo es que fueses capaz de interpretar la parte binaria para así tener la información completa del archivo, pero si no es relevante para tí, tu solución es buena.


Saludos.
  • 0