Escrito em December 30th, 2009 as 8:55 am por

1 Comentário

Quem já não se deparou com a situação de precisar converter uma string delimitada por tamanho e com layout fixo para poder utilizar os dados?

Por esse motivo que compartilho um componente muito útil que recebe o layout e o texto e converte em um array indexado pelo nome do campo.

Para o exemplo, iremos utilizar o layout abaixo:

// Nome: 40 posições
// Email: 40 posições
// Endereço: 43 posições
// Cidade: 18 posições
// Estado: 2 posições
// Pais: 6 posições

A Seguir, temos o código do componente:

namespace DotNetMax.Util
{
    /// <summary>
    /// Entidade para os Parâmetros
    /// </summary>
    public sealed class SizeDelimitedResultConverterItemParameter
    {
        private readonly string _ParameterName;
        private readonly int _ParameterOrder;
        private readonly int _Size;
        /// <summary>
        /// Inicializa o Parâmetro
        /// </summary>
        /// <param name="size">Indica o Tamanho (em Bytes) do Texto que Contém o Parâmetro</param>
        /// <param name="parameterOrder">Indica a Posição do Parâmetro na Hierarquia dos Parâmetros (1º, 2º, 3º, ...)</param>
        /// <param name="parameterName">Indica o Nome Único do Parâmetro</param>
        public SizeDelimitedResultConverterItemParameter(int size, int parameterOrder, string parameterName)
        {
            this._Size = size;
            this._ParameterOrder = parameterOrder;
            this._ParameterName = parameterName;
        }
        /// <summary>
        /// Contém o Nome Único do Parâmetro
        /// </summary>
        public string ParameterName
        {
            get { return _ParameterName; }
        }
        /// <summary>
        /// Contém o Tamanho (em Bytes) do Texto que Contém o Parâmetro
        /// </summary>
        public int Size
        {
            get { return _Size; }
        }
        /// <summary>
        /// Contém a Posição do Parâmetro na Hierarquia dos Parâmetros (1º, 2º, 3º, ...)
        /// </summary>
        public int ParameterOrder
        {
            get { return _ParameterOrder; }
        }
    }
    /// <summary>
    /// Conversor de String Limitada por Tamanho para Array
    /// </summary>
    public sealed class SizeDelimitedConverter
    {
        private readonly List<SizeDelimitedResultConverterItemParameter> _Parameters =
 new List<SizeDelimitedResultConverterItemParameter>();
        /// <summary>
        /// Computa o Tamanho Total dos Parâmetros para a Conversão
        /// </summary>
        private int TotalParameterLen
        {
            get
            {
                int total = 0;
                foreach (SizeDelimitedResultConverterItemParameter list in _Parameters)
                {
                    total += list.Size;
                }
                return total;
            }
        }
        /// <summary>
        /// Contém a Ordem do Parâmetro (Gerenciamento Interno)
        /// </summary>
        private int _ParameterOrder;
        /// <summary>
        /// Adiciona um Parâmetro
        /// </summary>
        /// <param name="size">Indica o Tamanho (em Bytes) do Texto que Contém o Parâmetro</param>
        /// <param name="parameterOrder">Indica a Posição do Parâmetro na Hierarquia dos Parâmetros (1º, 2º, 3º, ...)</param>
        /// <param name="parameterName">Indica o Nome Único do Parâmetro</param>
        public void AddParameter(int size, int parameterOrder, string parameterName)
        {
            this._Parameters.Add(new SizeDelimitedResultConverterItemParameter(size, parameterOrder, parameterName));
        }
        /// <summary>
        /// Adiciona um Parâmetro
        /// </summary>
        /// <param name="size">Indica o Tamanho (em Bytes) do Texto que Contém o Parâmetro</param>
        /// <param name="parameterName">Indica o Nome Único do Parâmetro</param>
        public void AddParameter(int size, string parameterName)
        {
            this.AddParameter(size, this._ParameterOrder, parameterName);
            this._ParameterOrder++;
        }
        /// <summary>
        /// Analisa o Retorno o Converte em uma Lista
        /// </summary>
        /// <param name="sizeDelimitedResult">Resultado Flat para ser Analisado</param>
        /// <param name="trimResult">Indica se o Resultado deve ter os Espaços em Branco Removidos</param>
        /// <returns>Retorna uma Lista com Nome do Parâmetro e Valor do Parâmetro</returns>
        /// <exception cref="InvalidOperationException">Caso não haja Parâmetros para serem Utilizados</exception>
        public Dictionary<string, string> Convert(string sizeDelimitedResult, bool trimResult)
        {
            // Verifica os Parâmetros
            if (_Parameters.Count == 0)
            {
                throw (new InvalidOperationException("É necessário ao menos um parâmetro"));
            }
            // Verifica se o Tamanho da String é Suficiente
            if (sizeDelimitedResult.Length < this.TotalParameterLen)
            {
                throw (new InvalidOperationException("O tamanho da string é incompatível com o layout informado"));
            }
            // Cria Objetos
            SortedList<int, object> sortedParameters = new SortedList<int, object>();
            Dictionary<string, string> resultList = new Dictionary<string, string>();
            int positionCounter = 0;
            string positionValue;
            // Adiciona os Parâmetros na Lista de Ordenação
            foreach (SizeDelimitedResultConverterItemParameter parameter in _Parameters)
            {
                sortedParameters.Add(parameter.ParameterOrder, parameter);
            }
            // Looping nos Parâmetros Ordenados
            foreach (SizeDelimitedResultConverterItemParameter parameter in sortedParameters.Values)
            {
                // Recupera Valor
                positionValue = sizeDelimitedResult.Substring(positionCounter, parameter.Size);
                // Adidiona na Lista
                resultList.Add(parameter.ParameterName, trimResult ? positionValue.Trim() : positionValue);
                // Atualiza Contador
                positionCounter = positionCounter + parameter.Size;
            }
             // Retorna Lista
             return resultList;
         }
     }
}

Exemplo de Uso:

 //
// Inicializa a String de Demo com o Layout já definido
//
string demoData = "Guilherme Bacellar Moralez              meulEmail@meuprovedor.com.br            R. dos Blogs, 544                          São Paulo         SPBrasil";
// Cria Conversor
SizeDelimitedConverter newConverter = new SizeDelimitedConverter();
// Adiciona o Layout
newConverter.AddParameter(40, "nome");
newConverter.AddParameter(40, "email");
newConverter.AddParameter(43, "endereco");
newConverter.AddParameter(18, "cidade");
newConverter.AddParameter(2, "estado");
newConverter.AddParameter(6, "pais");
// Realiza Conversão
Dictionary dictionary = newConverter.Convert(demoData, true);
// Recupera os Valores Convertidos
string nome = dictionary["nome"];
string email = dictionary["email"];
string endereco = dictionary["endereco"];
string cidade = dictionary["cidade"];
string estado = dictionary["estado"];
string pais = dictionary["pais"];

Espero que esse código possa ser muito útil, pois onde ele foi criado ele quebra muito galho para ler as respostas do MainFrame.

Se você gostou do post, deixe um comentário ou assine nosso RSS RSS.

Posts Relacionados:

  1. Converter um Array de Bytes para String e String para Array de Bytes
  2. Convertendo Caminhos Absolutos e URL’s Absolutas para Caminhos Relativos e URL’s Relativas
  3. Calculando CRC de Strings (Texto), Array’s e Arquivos
  4. Criando um documento Pdf com iTextSharp – Parte IV (Tamanho da Página)
  5. Clonando Objetos (.Clone()) sem Serialização
  6. Criando um documento Pdf com iTextSharp – Parte II
  7. Criando um documento Pdf com iTextSharp – Parte III (Rotacionar Folha)
, ,

1 Reposta to “Convertendo String Delimitada por Tamanho (Trancode) em Array”


  1. rafael

    1 year ago

    Parabéns! Excelente post! mas no caso da string conter um array, como vc faria?

Deixa uma Resposta

znjdb32s6g