none
Split de arquivos em C# RRS feed

  • Pergunta

  • Boa noite, pessoal.

    Estou com um problema em um cliente no qual estou enviando no e-mail dele um arquivo zip quebrado em 3 partes.
    O problema é que o anti-vírus do cliente acaba sempre excluindo o 1º arquivo, enquanto as outras partes acaba recebendo, sendo que chega apenas um anexo txt com a seguinte mensagem:
    "EmpresaXXX's virus protection has replaced attachment "anexo.zip0" with this text message. The original file was unscannable and was deleted."
    Alguém já passou por esse problema? A princípio eu acredito que o anti-vírus não consegue escanear este 1º arquivo por falta de algum cabeçalho nesse arquivo.
    Segue abaixo o método que estou utilizando para fazer o split do arquivo, só estou utilizando classes do próprio .NET para isso:

     

    FileStream fsIn = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    
    
    
    			string basePath = System.IO.Path.GetDirectoryName(fileName);
    
    
    
    			int fileSize = (int) fsIn.Length;
    
    			int segments = (int) (fileSize / m_segmentSize);
    
    			int remainder = (int) (fileSize % m_segmentSize);
    
    
    
    			if (remainder > 0) segments++;
    
    
    
    			byte[] buffer = new byte[blockSize];
    
    
    
    			for (int i = 0; i < segments; i++)
    
    			{
    
    				FileStream fsOut = new FileStream(fileName + "." + i, FileMode.Create,FileAccess.Write);
    
    				int blocks = (int) (m_segmentSize / blockSize);
    
    
    
    				if ( remainder > 0 && i < segments - 1)
    
    				{
    
    					for ( int j = 0; j < blocks ; j++)
    
    					{
    
    						//probably should just check the int ret value then write those blocks
    
    						// then if the ret value < 1024, just write the remainder & exit
    
    						fsIn.Read(buffer, 0, blockSize);
    
    						fsOut.Write(buffer, 0, blockSize);
    
    					}
    
    				}
    
    				else
    
    				{
    
    					int finalBlocks = (int) (remainder / blockSize);
    
    					int lastBlock = (int) (remainder % blockSize);
    
    					for (int k = 0; k < finalBlocks; k++)
    
    					{
    
    						fsIn.Read(buffer, 0, blockSize);
    
    						fsOut.Write(buffer,0,blockSize);
    
    					}
    
    					fsIn.Read(buffer, 0, lastBlock);
    
    					fsOut.Write(buffer, 0, lastBlock);
    
    				}
    
    				fsOut.Flush();
    
    				fsOut.Close();
    
    			}
    
    			fsIn.Close();
    
    

     


    Obs.: No caso, estou enviando cada arquivo em e-mails separados. E a versão que estou utilizando é .NET 1.1.


    Abraço,
    Marcelo Tamanini
    sexta-feira, 12 de março de 2010 22:21

Respostas

  • Marcelo,

    Acho que uma alternativa seria algum componente Zip de terceiros, como esse:

    http://www.componentace.com/.NET_zip_component_zipforge.htm

    Que tem tanto para o 1.1 2.0...
    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    segunda-feira, 15 de março de 2010 20:36
    Moderador
  • O grande problema é que os sistemas de filtro de e-mail ou anti-virus são basedos na extensão do arquivo ou conteúdo.
    Pelo o que vc mencionou somente o primeiro esta sendo barrado, isto porque o primeiro vem com a estensão zip ou exe que é barroda por política de segurança da Empresa.

    A solução é renomer o arquivo exemplo pra xxe ou xip.

    Um grande abraço.
    quarta-feira, 17 de março de 2010 01:33
  • Apesar de achar q a resposta do Andrew31 esta correta... vou deixando aqui um exemplo de spliter de arquivos para quem mais passar por aqui e tiver curiosidade d saber como funciona um:

    using System;
    using System.IO;
    
    namespace Split {
        class Program {
            static void Main(string[] args) {
                if (args.Length != 2) {
                    Program.Help();
                    return;
                }
    
                var filename = args[1];
                var option = args[0].Split(':');
                switch (option[0].ToLower()) {
                    case "/s":
                        if (option.Length != 2) {
                            Console.WriteLine("Parametro inválido: {0}", args[0]);
                            Program.Help();
                            return;
                        }
    
                        if (!File.Exists(filename)) {
                            Console.WriteLine("Arquivo inválido: {0}", filename);
                            Program.Help();
                            return;
                        }
    
                        int size = 0;
                        if (int.TryParse(option[1], out size)) {
                            Program.SplitFile(filename, size);
                        } else {
                            Console.WriteLine("Tamanho de arquivo inválido");
                            Program.Help();
                        }
                        return;
                    case "/j":
                        Program.JoinFile(filename);
                        return;
                    default:
                        Console.WriteLine("Parametro inválido: {0}", option[0]);
                        Program.Help();
                        return;
                }
            }
    
            static void Help() {
                Console.WriteLine();
                Console.WriteLine("Uso: split [/s:size] [/j] filename");
                Console.WriteLine("/s - Separar o arquivo no tamanho informado no paramero size (em Kb)");
                Console.WriteLine("/j - Juntar os arquivos (iniciando pelo arquivo informado em filename)");
                Console.WriteLine();
            }
    
            static void SplitFile(string filename, int size) {
                int index = 1;
                int bytesRead = 0;
                byte[] bytes = new byte[size * 1024];
                using (FileStream reader = File.OpenRead(filename)) {                
                    while ((bytesRead = reader.Read(bytes, 0, bytes.Length)) != 0) {
                        var target = String.Format("{0}.{1:00000}", filename, index++);
                        using(FileStream writer = File.OpenWrite(target)) {
                            writer.Write(bytes, 0, bytesRead);
                            writer.Flush();
                            writer.Close();
                        }
    	            }
                    reader.Close();
                }
    
                Console.WriteLine("O arquivo {0} foi dividido em {1} partes", filename, index - 1);
            }
    
            static void JoinFile(string filename) {
                var root = Path.GetDirectoryName(filename);
                var mask = Path.GetFileName(filename) + ".*";
                string[] fileParts = Directory.GetFiles(root, mask, SearchOption.TopDirectoryOnly);
    
                if (fileParts.Length == 0) {
                    if (!File.Exists(filename)) {
                        Console.WriteLine("Arquivo inválido: {0}", filename);
                        Program.Help();
                        return;
                    }
                }
    
                using (FileStream writer = File.OpenWrite(filename)) {
                    for (int i = 0; i < fileParts.Length; i++) {
                        byte[] bytes = File.ReadAllBytes(fileParts[i]);
                        writer.Write(bytes, 0, bytes.Length);
                        writer.Flush();
                        File.Delete(fileParts[i]);
                    }
                    writer.Close();
                }
    
                Console.WriteLine("O arquivo {0} foi criado com sucesso", filename);
            }
        }
    }
    

    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    quarta-feira, 17 de março de 2010 03:46
    Moderador

Todas as Respostas

  • Alguém aqui pelo menos já utilizou a dll sharpziplib? Saberiam me dizer se existe alguma classe ou método nesta dll para fazer split de arquivos? Não encontrei nenhum exemplo aqui, até mesmo no help da dll.

    Abraço,
    Marcelo Tamanini
    segunda-feira, 15 de março de 2010 14:38
  • segunda-feira, 15 de março de 2010 14:52
  • Desses 3 links, apenas o 2º não testei, mas acredito que vai dar na mesma.
    Eu já tentei enviar diretamente um pdf quebrado em duas partes e o anti-vírus barrou também. Mas é sempre a 1ª parte que é barrada, as partes seguintes acabam chegando no cliente. Pela mensagem dá a entender que o anti-vírus não conseguiu escanear e por isso excluiu:
    "EmpresaXXX's virus protection has replaced attachment "anexo.zip0" with this text message. The original file was unscannable and was deleted."
    No caso, o anti-vírus está lendo a 1ª parte que tem o cabeçalho e nisso ele verifica que o tamanho não bate com o tamanho original, enquanto as outras partes são apenas dados binários, não contendo nenhum cabeçalho, o anti-vírus acaba deixando passar, é isso ou viajei?

    Obs.: Se eu enviar o arquivo zip completo, ou seja, sem estar quebrado, o cliente recebe. O problema é que preciso quebrar quando o arquivo ultrapassada 2MB.


    Abraço,
    Marcelo Tamanini
    segunda-feira, 15 de março de 2010 16:37
  • Olá Marcelo,

    hoje precisei de manipular arquivos '.zip' encontrei essa biblioteca que achei bem interessante e suporta 'split' de arquivos!! Ela é free (open source), simples de utilizar e bem madura. Segue o link: http://dotnetzip.codeplex.com/

    Espero ter ajudado.


    segunda-feira, 15 de março de 2010 18:41
  • Só tem um problema, estou utilizando o framework 1.1 nesse projeto e não é possível atualizar o projeto agora. rsrs
    Abraço,
    Marcelo Tamanini
    segunda-feira, 15 de março de 2010 19:26
  • Marcelo,

    Acho que uma alternativa seria algum componente Zip de terceiros, como esse:

    http://www.componentace.com/.NET_zip_component_zipforge.htm

    Que tem tanto para o 1.1 2.0...
    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    segunda-feira, 15 de março de 2010 20:36
    Moderador
  • Eu até já estou utilizando um componente de terceiro para zipar, só que não encontrei opção para fazer split. No caso é a sharpZipLib.
    Esse que você me passou é pago, certo?
    Eu queria achar uma free, mas é quase impossível achar algo para .net 1.1, só achei mesmo esse "sharpZipLib".
    Abraço,
    Marcelo Tamanini
    terça-feira, 16 de março de 2010 16:10
  • Marcelo,

    Sim... Esse é pago...

    Não tenho ideia de se isso é possível na SharpZipLib... Eles não têem um fórum de discussão?
    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    terça-feira, 16 de março de 2010 18:33
    Moderador
  • O grande problema é que os sistemas de filtro de e-mail ou anti-virus são basedos na extensão do arquivo ou conteúdo.
    Pelo o que vc mencionou somente o primeiro esta sendo barrado, isto porque o primeiro vem com a estensão zip ou exe que é barroda por política de segurança da Empresa.

    A solução é renomer o arquivo exemplo pra xxe ou xip.

    Um grande abraço.
    quarta-feira, 17 de março de 2010 01:33
  • Apesar de achar q a resposta do Andrew31 esta correta... vou deixando aqui um exemplo de spliter de arquivos para quem mais passar por aqui e tiver curiosidade d saber como funciona um:

    using System;
    using System.IO;
    
    namespace Split {
        class Program {
            static void Main(string[] args) {
                if (args.Length != 2) {
                    Program.Help();
                    return;
                }
    
                var filename = args[1];
                var option = args[0].Split(':');
                switch (option[0].ToLower()) {
                    case "/s":
                        if (option.Length != 2) {
                            Console.WriteLine("Parametro inválido: {0}", args[0]);
                            Program.Help();
                            return;
                        }
    
                        if (!File.Exists(filename)) {
                            Console.WriteLine("Arquivo inválido: {0}", filename);
                            Program.Help();
                            return;
                        }
    
                        int size = 0;
                        if (int.TryParse(option[1], out size)) {
                            Program.SplitFile(filename, size);
                        } else {
                            Console.WriteLine("Tamanho de arquivo inválido");
                            Program.Help();
                        }
                        return;
                    case "/j":
                        Program.JoinFile(filename);
                        return;
                    default:
                        Console.WriteLine("Parametro inválido: {0}", option[0]);
                        Program.Help();
                        return;
                }
            }
    
            static void Help() {
                Console.WriteLine();
                Console.WriteLine("Uso: split [/s:size] [/j] filename");
                Console.WriteLine("/s - Separar o arquivo no tamanho informado no paramero size (em Kb)");
                Console.WriteLine("/j - Juntar os arquivos (iniciando pelo arquivo informado em filename)");
                Console.WriteLine();
            }
    
            static void SplitFile(string filename, int size) {
                int index = 1;
                int bytesRead = 0;
                byte[] bytes = new byte[size * 1024];
                using (FileStream reader = File.OpenRead(filename)) {                
                    while ((bytesRead = reader.Read(bytes, 0, bytes.Length)) != 0) {
                        var target = String.Format("{0}.{1:00000}", filename, index++);
                        using(FileStream writer = File.OpenWrite(target)) {
                            writer.Write(bytes, 0, bytesRead);
                            writer.Flush();
                            writer.Close();
                        }
    	            }
                    reader.Close();
                }
    
                Console.WriteLine("O arquivo {0} foi dividido em {1} partes", filename, index - 1);
            }
    
            static void JoinFile(string filename) {
                var root = Path.GetDirectoryName(filename);
                var mask = Path.GetFileName(filename) + ".*";
                string[] fileParts = Directory.GetFiles(root, mask, SearchOption.TopDirectoryOnly);
    
                if (fileParts.Length == 0) {
                    if (!File.Exists(filename)) {
                        Console.WriteLine("Arquivo inválido: {0}", filename);
                        Program.Help();
                        return;
                    }
                }
    
                using (FileStream writer = File.OpenWrite(filename)) {
                    for (int i = 0; i < fileParts.Length; i++) {
                        byte[] bytes = File.ReadAllBytes(fileParts[i]);
                        writer.Write(bytes, 0, bytes.Length);
                        writer.Flush();
                        File.Delete(fileParts[i]);
                    }
                    writer.Close();
                }
    
                Console.WriteLine("O arquivo {0} foi criado com sucesso", filename);
            }
        }
    }
    

    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    quarta-feira, 17 de março de 2010 03:46
    Moderador