none
Dividir arquivo em partes sem quebrar suas linhas RRS feed

Respostas

  • Olá Lúcio,

    Se o arquivo é grande, então deverá ler o arquivo aos poucos utilizando um Stream, sem ter de carregar o arquivo inteiro para a memória de uma só vez. Para escrever nos arquivos de saída (divididos) é a mesma coisa... Utiliza um Stream de escrita para escrever as linhas do arquivo de entrada nos diferentes arquivos de saída.

    O mais importante é definir o critério de separação dos arquivos... Por quantidade de linhas? Por quantidade de bytes (+ ou -) sem truncar a linha?

    Seja qual for o critério / lógica para dividir os arquivos, você só precisa ir trocando o arquivo de saída conforme vai lendo as linhas do arquivo de entrada.

    Abaixo envio um exemplo de como poderia fazer para dividir um arquivo texto em vários arquivos diferentes com 5 linhas cada um (sendo que o último vai ter sempre o que sobrar, pode ser 5 linhas, ou 4... 3... 2... ou 1).

    const string nomeArquivoOrigem = @"C:\Pasta\Origem.txt";
    const string nomeArquivoDestino = @"C:\Pasta\Destino-{0}.txt";
    const int linhasPorArquivo = 5;
                
    using (var arquivoOrigem = new StreamReader(nomeArquivoOrigem))
    {
        var contadorArquivos = 0;
        var arquivoDestino = new StreamWriter(string.Format(nomeArquivoDestino, contadorArquivos + 1));
    
        try
        {
            var contadorLinhas = 0;
    
            string linha;
            while ((linha = arquivoOrigem.ReadLine()) != null)
            {
                if (contadorLinhas >= linhasPorArquivo)
                {
                    contadorLinhas = 0;
                    contadorArquivos++;
    
                    arquivoDestino.Dispose();
                    arquivoDestino = new StreamWriter(string.Format(nomeArquivoDestino, contadorArquivos + 1));
                }
    
                arquivoDestino.WriteLine(linha);
                contadorLinhas++;
            }
        }
        finally
        {
            arquivoDestino.Dispose();
        }
    }
    

    Abraços,
    Caio Proiete

     


    Caio Proiete
    Microsoft MVP, MCT, MCPD, MCTS, MCSD
    http://caioproiete.net
    • Sugerido como Resposta Danimar Ribeiro domingo, 29 de julho de 2012 16:41
    • Marcado como Resposta Lúcio Charallo sexta-feira, 18 de setembro de 2015 19:22
    domingo, 29 de julho de 2012 12:57
    Moderador

Todas as Respostas

  • Vi uma thread no StackOverflow que acho que pode lhe ajudar. Nesse caso a solução foi utilizar um Regex. Caso lhe atenda, você vai precisar editar um pouco o código para que se adapte à sua demanda. 

    string[] lines =  Regex.Split(tbIn.Text, @"(?<=\r\n)(?!$)");


    Se a sugestão resolver o problema, favor marcar como Resposta.

    sexta-feira, 20 de julho de 2012 15:12
  • Acho que essa não é uma boa alternativa, para isso seria necessário carregar todas as linhas na memória de uma única vez e pelo tamanho dos arquivos não é viável, pois os arquivos possuem +/- 5GB.
    sexta-feira, 20 de julho de 2012 16:30
  • Olá Lúcio,

    Se o arquivo é grande, então deverá ler o arquivo aos poucos utilizando um Stream, sem ter de carregar o arquivo inteiro para a memória de uma só vez. Para escrever nos arquivos de saída (divididos) é a mesma coisa... Utiliza um Stream de escrita para escrever as linhas do arquivo de entrada nos diferentes arquivos de saída.

    O mais importante é definir o critério de separação dos arquivos... Por quantidade de linhas? Por quantidade de bytes (+ ou -) sem truncar a linha?

    Seja qual for o critério / lógica para dividir os arquivos, você só precisa ir trocando o arquivo de saída conforme vai lendo as linhas do arquivo de entrada.

    Abaixo envio um exemplo de como poderia fazer para dividir um arquivo texto em vários arquivos diferentes com 5 linhas cada um (sendo que o último vai ter sempre o que sobrar, pode ser 5 linhas, ou 4... 3... 2... ou 1).

    const string nomeArquivoOrigem = @"C:\Pasta\Origem.txt";
    const string nomeArquivoDestino = @"C:\Pasta\Destino-{0}.txt";
    const int linhasPorArquivo = 5;
                
    using (var arquivoOrigem = new StreamReader(nomeArquivoOrigem))
    {
        var contadorArquivos = 0;
        var arquivoDestino = new StreamWriter(string.Format(nomeArquivoDestino, contadorArquivos + 1));
    
        try
        {
            var contadorLinhas = 0;
    
            string linha;
            while ((linha = arquivoOrigem.ReadLine()) != null)
            {
                if (contadorLinhas >= linhasPorArquivo)
                {
                    contadorLinhas = 0;
                    contadorArquivos++;
    
                    arquivoDestino.Dispose();
                    arquivoDestino = new StreamWriter(string.Format(nomeArquivoDestino, contadorArquivos + 1));
                }
    
                arquivoDestino.WriteLine(linha);
                contadorLinhas++;
            }
        }
        finally
        {
            arquivoDestino.Dispose();
        }
    }
    

    Abraços,
    Caio Proiete

     


    Caio Proiete
    Microsoft MVP, MCT, MCPD, MCTS, MCSD
    http://caioproiete.net
    • Sugerido como Resposta Danimar Ribeiro domingo, 29 de julho de 2012 16:41
    • Marcado como Resposta Lúcio Charallo sexta-feira, 18 de setembro de 2015 19:22
    domingo, 29 de julho de 2012 12:57
    Moderador