Ver Mensaje Individual
  #7  
Antiguo 19-07-2019
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Reputación: 11
bucanero Va camino a la fama
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Vaya, eso es de 2015.
Se me ocurre que también puedes hacer una sustitución de las ñ,á,é,í,ó,ú antes de importar las líneas.
Gracias Casimiro!! es la solución que al final he implementado. No es la mas optima, puesto que si el fichero en algún momento incluye otros caracteres en UTF8 tendré entonces que modificar nuevamente el código. Pero de momento me sirve como solución.

Aquí dejo el código que he implementado:

Código Delphi [-]

function UTF8ToAnsii(const value: string): string;
/// convierte los caracteres codificados en UTF8 a ANSI
const
  SpecialChars: array[0..5] of string = ('ñ', 'á', 'é', 'í', 'ó', 'ú');
var
  i: LongInt;
begin
  result := value;
  for i := 0 to High(SpecialChars) do
    result := StringReplace(result,
         // caracter especial en codificacion UTF8
      SpecialChars[i],
         // el mismo caracter en codificacion ANSII
      TEncoding.ANSI.GetString(TEncoding.UTF8.GetBytes(SpecialChars[i])), [rfReplaceAll]);
end;

function RepairFileUTF8(const AFileName: string): boolean;
/// Lee un fichero en formato ANSI y lo escribe en formato UTF8
var
  content: string;
begin
  try
    result := false;
    // lee el contenido del fichero en formato ANSII
    content := Tfile.ReadAllText(AFileName);
    //Sustituye los caracteres especiales codificados en UTF8 a codificacion ANSII
    // y convierte todo el contenido del fichero a UTF8
    content := UTF8Decode(UTF8ToAnsii(content));
    // guarda de nuevo el fichero ya con formato UTF8
    Tfile.WriteAllText(AFileName, content, TEncoding.UTF8);
    result := true;
  except
    on E: Exception do
      MessageDlg(E.message, mtError, [mbOK], 0);
  end;
end;

function IsValidUTF8Format(const AFileName: string): Boolean;
var
  intento: integer;
begin
  result := false;
  intento := 2;
  repeat
    try
      dec(intento);
      // se intenta leer el contenido del fichero en formato UTF8
      Tfile.ReadAllText(AFileName, TEncoding.UTF8);
      result := true;
    except
      on E: Exception do begin
        if (e.Message = SNoMappingForUnicodeCharacter) then begin
          if (intento > 0) then
            //si da error se intenta reparar. (solo lo hace la primera vez)
            RepairFileUTF8(AFileName)
          else
            // si diera error por segunda vez segunda vez, es porque el fichero
            // contiene mas caracteres especiales no incluidos en la lista de sustitucion
            MessageDlg('Revise caracteres especiales UTF8 en el fichero', mtError, [mbOK], 0);
        end;
      end;
    end;
  until result or (intento <= 0);
end;

y la forma de utilizarlo es:
Código Delphi [-]
  if not IsValidUTF8Format(NameFile) then
    MessageDlg('El fichero no tiene un formato valido ', mtError, [mbOK], 0)
  else
    OpenFile(NameFile);


Gracias por vuestro tiempo y las soluciones aportadas.
Un saludo
Responder Con Cita