Recentemente, estou fazendo um requisito: faça o download do arquivo que armazena o URL da imagem no diretório FTP de outros sistemas e leia o endereço da URL no arquivo, faça o download da imagem de acordo com o endereço e compacte -o em um pacote em um dia. Em média, um arquivo de endereço contém cerca de 4.000 endereços. Ou seja, depois de digitalizar um arquivo, você precisa baixar cerca de 4.000 fotos e depois comprimi -lo. Os seguintes registros meu método de implementação e processo de otimização. Se você tiver alguma maneira melhor, pode compartilhá -lo.
Estrutura usada: springmvc
Implementação de tarefas cronometradas: herança org.springframework.scheduling.quartz.quartzjobbean;
Não vou falar sobre a construção do ambiente FTP. Eu o gravei em outros blogs que eu uso o serviço FTP criado pelo CentOS na máquina virtual para criar uma conta FTP e diretório correspondente e fazer upload do arquivo de endereço da imagem que precisa ser baixado com antecedência. Formato de conteúdo do arquivo "ID da imagem || Endereço da imagem".
Método 1. A maneira mais fácil de implementá -lo é primeiro baixar o arquivo que armazena o endereço URL da imagem e, em seguida, leia o arquivo atravessando o endereço da imagem, ajuste o método de imagem baixado para armazenar a imagem localmente e, finalmente, compactar a imagem baixada. Após a conclusão, exclua a imagem baixada e mantenha apenas o pacote compactado.
classe pública PictureTransferjob estende o quartzjobbean {o void protegido ExecuteInternal (JobExecutionContext arg0) lança JobExecutionException {// A configuração real do FTP é obtida lendo o arquivo de configuração // ftp string string hostname = "192.168.112.112"; // porta FTP Int Port = 2001; /FTP Conta String UserName = "Test1"; // ftp senha string senha = "test1"; // diretório de armazenamento de arquivo ftp string ftpDowload = "/"; // o caminho de armazenamento local do caminho da sequência do arquivo = this.getClass (). GetResource ("/"). GetPath (); // O diretório de armazenamento do arquivo de endereço da imagem string addrpath = path.substring (1, path.indexOF ("web-inf/classes"))+"picaddr"; // O diretório de armazenamento de imagem baixado real realizado string picpath = path.substring (1, path.indexOF ("web-inf/classes"))+"pic"; addrpath = addrpath.replace ("%20", ""); picpath = picpath.Replace ("%20", ""); tente {// crie o arquivo cretfile (addrpath); // Crie o arquivo cretfile (picpath); String oldaddrpath = addrpath; String OldpicPath = picpath; // Crie a conexão FTP ftputil2 ftputil2 = new ftputil2 (nome do host, porta, nome de usuário, senha, ftpDowload, true); // transf o arquivo no diretório ftp string [] arquivos = ftputil2.listallfiles (); // O banco de dados local terá um registro de tabela dos arquivos baixados. Aqui vamos consultar o banco de dados e os nomes de arquivos listados no FTP. Se os arquivos baixados não serão baixados e evite downloads repetidos. // O processo de comparação é omitido abaixo, loop a matriz de arquivos e crie o arquivo localmente para (int i = 0; i <files.length; i ++) {cretfile (addrpath+file.separator+nome do arquivo); // ftpDowload é o endereço do servidor FTP para armazenar o arquivo, o addrpath é o endereço do arquivo de armazenamento local // aqui está um status de retorno para determinar se o arquivo é baixado com sucesso boolean downloadInvestorflag = ftputil2.downloadfile (ftpDowload, addrPath); // Um método para ler o arquivo após o download do arquivo é baixado com sucesso, e o endereço da imagem a ser baixado é armazenado no contêiner boolean entitystate = setPicturetail (addrpath, picpath, filenamedate); }} catch (Exceção e) {e.printStackTrace (); // Clique na classe Business que registra o log de erros para enviar mensagens de texto que baixam erros de arquivo}} // comece a ler o endereço da imagem aqui private boolean setPicturetail (string addrpath, string picpath, string symate) { System.out.println("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- String row; int count = 0; addrmap.put (coluna [0] .TRIM (), coluna [1] .TRIM (); System.out.println (new Date ()); System.out.println ("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- E.PrintStackTrace (); String Picaddr = NULL; Array de byte através do InputStream e perderá dados, resultando em imagens baixadas incompletas. Array e, após a leitura, os dados no fluxo são limpos = novo arquivo PicPath+FileName+"JPG"); is.close (); Zippic (Picpath, Syncdate, Addrmap); {// Faça uma pausa na lista de arquivos que precisam ser compactados e o nome do arquivo compactado ziputil.zipbyStream (piclist, novo arquivo (arquivo picpath+Syndate+". Zip"); if (! file.exists ()) {file.mkdirs (); Método 2: Download multithread, compactação direta de fluxos
Método 1 Embora as funções básicas sejam implementadas, porque há muitas imagens que precisam ser baixadas, e a compactação de arquivos de imagem local e a exclusão de imagens também é demorada, para que haja dois lugares onde você possa otimizar a velocidade. Um é melhorar a eficiência do download de imagens, e o outro é melhorar a eficiência da compressão.
O método para melhorar a eficiência de download pode usar downloads multidreados, e o método para melhorar a eficiência da compressão pode comprimir diretamente o fluxo de arquivos sem salvar a imagem localmente.
Método de implementação de multi-thread: Primeiro, salvamos a lista de endereços de arquivos que precisam ser baixados. Se quisermos usar o multi-threading para fazer o download, devemos garantir que as imagens baixadas por threads diferentes não sejam repetidas. Portanto, é necessária uma bandeira para distingui -los. No momento, podemos usar um contador de índice para dividi -los de acordo com uma certa quantidade de fotos baixadas por cada thread. A partir de 0, a cada 400 imagens, podemos usar um thread para baixar sempre, para que possamos determinar o número de threads necessários e as imagens baixadas por cada thread não serão repetidas.
Método de implementação de arquivos compactados: como a essência da geração de arquivos compactados é ler o fluxo de arquivos que precisa ser compactado e, em seguida, gerar um pacote compactado, podemos usar o contêiner para armazenar os dados do fluxo de imagens baixados por todos os threads em vez de criar o arquivo de imagem baixado e depois passar os dados do fluxo para a classe de ferramentas de compressão para mantê -lo diretamente. Isso omite o processo tedioso de ler o arquivo de imagem para criar o fluxo e, em seguida, gerar o pacote compactado e excluir o arquivo de imagem local.
As principais implementações da transformação estão listadas abaixo:
/ *** Comprimido as imagens baixadas por dia* @THOWSoException*/ Private boolean zippic (string picpath, string syndate, map <string, string> addrmap) lança ioexception {// Como é um string de mapa de threads Multi-thread, um mapa de thread-sure é necessário. ConcurrentHashMap <String, InputStream> (); // O número de imagens baixadas por cada thread é definido aqui int conting = 400; // Armazene o endereço da imagem que precisa ser baixado Lista <Entrada <String, String >> addrlist = new ArrayList <Entrada <String, String >> (addrmap.entrySet ()); // O número de threads, adicione um porque você deseja criar um thread para baixar as últimas menos de 400 imagens int nthreads = (addrlist.size ()/count) +1; // CountDownLatch CountDownLatch = new CountDownLatch (NTHREADS); tente {boolean downpic = false; // Executa o download multithread Pictures Downpic = Downpic (Picpath, Addrlist, Piclist, PictureList, Nthreads, Count); if (downpic) {ziputil.zipbyArray (piclist, novo arquivo (picpath+syncate+". zip")); } retornar true; } catch (Exceção e) {e.printStackTrace (); retornar falso; }}Aqui está a criação de um pool de threads
/ *** Faça o download da imagem de acordo com o endereço da URL* @THOWS INTERRUPEDEXCECCECTION*/ Private Boolean Downpic (String Picpath, List <Entrada <String, String >> Addrlist, map <String, Byte []> Piclist, Map <String, InputStream> PictureList, Int nthreads, INTROUN) threadpool = executores.newfixedthreadpool (nthreads); // Crie dois contadores CountDownLatch BEGN = new CountdownLatch (0); CountDownLatch end = new Countdownlatch (NTHREADS); // loop crie thread para (int i = 0; i <nthreads; i ++) {list <entrada <string, string >> subaddrlist = null; // Calcule os dados executados por cada thread if ((i + 1) == nthreads) {int startIndex = (i * count); int endindex = addrlist.size (); subaddrlist = addrlist.sublist (startIndex, endindex); } else {int startIndex = (i * count); int endindex = (i + 1) * contagem; subaddrlist = addrlist.sublist (startIndex, endindex); } // thread classe picdownload myhead = new picdownload (picpath, subaddrlist, piclist, pictureList); // A maneira de executar threads aqui é chamar o método Threadpool.execute (myhead) no pool de threads. tente {threadpool.execute (myhead); } catch (Exceção e) {// Log de erro de registro retornar false; }} Begin.CountDown (); end.await (); // fechar o thread pool threadpool.shutdown (); // Aqui você deve fazer um loop até que todos os threads no pool de threads tenham terminado antes de descer. Devido a esta etapa durante o teste, o tópico infantil baixou a imagem, mas não foi concluído, e o tópico principal caiu, resultando em nenhuma figura no pacote compactado // você também pode usar o Countdownlatch para implementar/*while ("True) {if (threadpool.istermined ()) {System.out.println (" Todos os threads threads endaram! quebrar; }}*/ retorna true; }A seguir é a implementação do thread
class PicDownload implementa Runnable {// Baixe a lista de endereços da lista de fotos <Entrada <String, String >> addrlist; // Carregar a lista de imagens baixadas com sucesso mapa <string, byte []> piclist; Mapa <string, inputStream> pictureList; // O caminho de armazenamento local da imagem da string picpath; Countdownlatch começa, final; public picdownload (string picpath, list <entrada <string, string >> addrlist, map <string, inputStream> piclist, countdownlatch BEGIN, Countdownlatch end) {this.addrlist = addrlist; this.picList = piclist; this.picpath = picpath; this.Begin = BEGIN; this.end = end; } @Override public void run () {try {System.out.println (thread.currentThread (). GetName ()+"------"+thread.currentThread (). GetId ()); picture (addrlist); //System.out.println (CountdownLatch.getCount ()); Begin.await (); } catch (Exceção e) {e.printStackTrace (); } finalmente {end.countdown (); //countdownlatch.countdown (); }} public boolean DowndPicture (List <Entrada <String, String >> addrlist) lança a exceção {inputStream is = null; FileOutputStream fos = null; Url url = nulo; String filename = null; String picaddr = nulo; FILO PIC = NULL; tente {for (map.entry <string, string> addrentry: addrlist) {filename = addrentry.getKey (); picaddr = addrentry.getValue (); // Crie o objeto URL url = novo URL (picaddr); é = url.openstream (); // O fluxo obtido pelo URLConnection será gravado diretamente na matriz de bytes através do InputStream e perderá dados, resultando em imagens baixadas incompletas. Use org.apache.commons.io.ioutils.tobytearray (urlconnection.openstream ()) para resolver // byte [] bytes = ioutils.tobytearray (IS); // novo byte [is.Available ()]; Os bytes obtidos // os dados no fluxo são lidos na matriz de bytes. Depois de ler, os dados no fluxo são limpos piclist.put (nome do arquivo+". Jpg", é); // No momento, como o fluxo não é gravado no arquivo, o fluxo não deve ser fechado; caso contrário, os dados no fluxo serão perdidos //is.close (); } retornar true; } catch (Exceção e) {e.printStackTrace (); retornar falso; } finalmente {// o fluxo não pode ser fechado/*se (null! = is) {is.close (); }*/}}} Encontrei outro problema usando fluxos para compactação acima. Ao comprimir o arquivo, java.net.socketexception: redefinição de conexão
Depois de analisar o motivo, deve ser que o fluxo InputStream e o URLConnection estejam no estado de conexão, e o tempo limite do URLConnection faz com que o fluxo de entrada não obtenha.
Tentei definir o tempo de tempo limite da URLConnection, mas durante o teste, descobri que a velocidade da rede do download da imagem recebida foi bastante afetada. Este método é muito instável e indesejável. No final, desisti apenas do fluxo e usei uma matriz de bytes para passar para a classe de ferramentas de compressão e depois converti a matriz de bytes para transmitir compactação.
/ ***Use o contêiner para armazenar a imagem de byte de imagem baixada*/ public boolean DownPicture (list <Entrada <string, string >> addrlist) lança exceção {inputStream Is = null; FileOutputStream fos = null; Url url = nulo; String filename = null; String picaddr = nulo; FILO PIC = NULL; tente {for (map.entry <string, string> addrentry: addrlist) {filename = addrentry.getKey (); picaddr = addrentry.getValue (); // Crie o objeto URL url = novo URL (picaddr); // Abra a conexão e crie o objeto java.net.urlConnection. Este objeto não tem método para fechar a conexão. Ele pode ser convertido em sua subclasse httpurlConnection para chamar o método de desconexão para fechar a conexão. //java.net.urlConnection e java.net.httpurlConnection Ambos os métodos de tempo limite para fechar a conexão // httpurlConnection uc = (httpurlConnection) url.openconnection (); é = uc.getInputStream (); // O fluxo obtido pelo URLConnection será gravado diretamente na matriz de bytes através do InputStream e perderá dados, resultando em imagens baixadas incompletas. Use org.apache.commons.io.ioutils.tobytearray (urlconnection.openstream ()) para resolver byte [] bytes = ioutils.tobyteArray (is); // novo byte [is.Available ()]; Os dados de bytes obtidos // no fluxo são lidos na matriz de bytes. Depois de ler, os dados no fluxo são limpos //is.read(bytes); piclist.put (nome do arquivo+". jpg", bytes); is.close (); } retornar true; } catch (Exceção e) {e.printStackTrace (); retornar falso; } finalmente {if (null! = is) {is.close (); }}} Resumir:
Problemas encontrados durante a implementação:
1. Ao usar o pool de threads, para o estado compartilhado, por exemplo, o contêiner de dados de bytes de imagem armazenado aqui é compartilhado por todos os threads; portanto, um contêiner sincronizado é necessário, caso contrário, causará problemas com os dados armazenados. Portanto, simultaneamente é usado.
2. Há um problema com a ordem de execução do thread principal e o tópico infantil aqui, porque o thread principal precisa aguardar todos os threads no pool de threads para terminar de baixar imagens antes de descer para compactar imagens. Se o thread principal não esperar que o thread filho termine e execute o método de compactação para baixo, ele levará a imagens ausentes ou sem imagens compactadas. Portanto, você pode usar o CountDownLatch para implementá -lo ou usar um loop morto para verificar o ThreadPool.isterMined () na instrução Pool de threads de fechamento para continuar executando o thread principal para comprimir a imagem.
3. Como o fluxo de entrada obtido pela URLConnection é transmitido diretamente à classe compactada para compactação, há uma situação em que o tempo limite da conexão é redefinido; portanto, o fluxo baixado é armazenado em uma matriz de bytes e depois passou para a classe compactada para comprimir para evitar situações inesperadas ao usar o fluxo.
4. Depois de usar o URLConnection.openstream () para obter o fluxo de entrada, a imagem que você converteu em uma matriz de bytes para download é incompleta. . Ele pode ser resolvido usando org.apache.commons.io.ioutils.tobytearray (urlConnection.openstream ()). Para detalhes, você pode ler o código -fonte para visualizar a implementação.
A seguir, a implementação da classe de ferramentas FTP:
importar java.io.bufferInputStream; importar java.io.bufferedOutputStream; importar java.io.fileInputStream; importar java.io.fileOutputStream; importar java.io.ioException; importar org.apache.commons.net.ftp.ftpClient; importar org.apache.commons.net.ftp.ftpclientConfig; importar org.apache.commons.net.ftp.ftpConnectionCledException; importar org.apache.commons.net.ftp.ftpreply; classe pública ftputil2 {private ftpClient ftpClient = null; // Endereço do servidor FTP Nome do host private String; // Port padrão do servidor FTP Public public static int defaultport = 21; // Nome de login String private Nome de usuário; // Login Senha Private String Senha; // Diretório remoto para acessar a String privada Remotelir; / ** * @param hostName * Endereço do host * @param porta * número da porta * @param nome de usuário * nome de usuário * @param senha * senha * @param remotedir * diretório de trabalho padrão * @param is_zhtimeZone * se é o lado do servidor ftp chinês * @return * @return */ ** * new me método */ public ftpput FtppTIl2 () @PeRUNT */ ** ** * new)/ public ftpputil () @PeRUNT */ ** * Propconfig.loadConfig ("System.properties"); String hostName = config.getConfig ("ftpaddress"); Porta string = config.getConfig ("ftpport"); String userName = config.getConfig ("ftpuserName"); String senha = config.getConfig ("ftppassword"); String remoterir = config.getConfig ("remotefilepath"); boolean is_zhtimeZone = true; this.hostname = hostName; this.UserName = Nome de usuário; this.password = senha; this.Remoterir = remotedir == null? "": Remotedir; this.ftpClient = new ftpClient (); if (is_zhtimeZone) {this.ftpclient.configure (ftputil2.config ()); this.ftpclient.setControlencoding ("GBK"); } // Conecte-se(); // Alterne o diretório this.Changedir (this.RemotedIr); this.setFileType (ftpClient.binary_file_type); ftpClient.SetDefaultPort (Integer.Parseint (porta)); } public ftputil2 (string hostName, int porta, string nome de usuário, senha de string, string remoterir, boolean is_zhtimeZone) {this.hostname = hostName; this.UserName = Nome de usuário; this.password = senha; defaultport = porta; this.Remoterir = remotedir == null? "": Remotedir; this.ftpClient = new ftpClient (); if (is_zhtimeZone) {this.ftpclient.configure (ftputil2.config ()); this.ftpclient.setControlencoding ("GBK"); } // efetue login para este.login (); // Alterne o diretório this.Changedir (this.RemotedIr); this.setFileType (ftpClient.ascii_file_type); ftpClient.SetDefaultPort (porta); } / *** Faça login no servidor FTP* / public boolean login () {boolean suced = false; tente {ftpclient.connect (this.hostname, defaultport); ftpClient.login (this.username, this.password); int reply; Responder = ftpClient.getReplyCode (); if (! ftpreply.ispositiveciction (resposta)) {ftpclient.disconnect (); sucesso de sucesso; }} Catch (ftpConnectionCledException e) {// TODO BLOCO DE CATAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); } sucesso = true; System.out.println ("Conecte -se ao servidor FTP:" + this.hostname + "succcess..start login"); sucesso de sucesso; } private static ftpClientConfig config () {ftpClientConfig conf = new FTPClientConfig (ftpClientConfig.syst_unix); conf.SetReCentDateFormatStr ("MM DD DD DD HH: MM"); // conf.SetReCentDateFormatStr ("(ano AAAA)? retornar conf; } / ** * Alterar diretório de trabalho * * @param remoteririr * * / public void alterações (string remoterir) {try {this.remotedir = remoterir; ftpClient.ChangeWorkingDirectory (RemotedIr); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); } System.out.println ("Altere o diretório de trabalho para:" + Remotelir); } / ** * Retorne ao diretório de nível anterior (diretório pai) * / public void ToparentDir () {try {ftpclient.ChangetoparentDirectory (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); }} / ***Liste todos os arquivos no diretório de trabalho atual* / public string [] listallfiles () {string [] nomes = this.listfiles ("*"); retornar este.sort (nomes); } / ** * Liste os arquivos correspondentes no diretório de trabalho especificado * * @param dir * exp: / cim / * @param file_regex * o curinga é * * / public string [] listallfiles (string dir, string file_regex) {string [] nomes = this.listfiles (dir + file_regex); retornar este.sort (nomes); } /** * Lista arquivos correspondentes * * @param file_regex * correspondem aos caracteres, os caracteres selvagens são * * /public String [] listfiles (string file_regex) {try { /** * ftpfile [] remotefiles = ftpclient.listfiles (file_regex); * //System.out.println(remotefiles.length); String [] nome = new * string [remotefiles.length]; if (remotefiles! = null) {for (int * i = 0; i <remotefiles.length; i ++) {if (remotefiles [i] == null) * nome [i] = ""; else * if (remotefiles [i] .getName () == NULL || Remotefiles * [i] .getName (). Equals * (".") || Remotefiles [i] .getName (). Equals ("..")) {name [i] = "" "; *} else nome [i] = remotefiles [i] .getName (); * System.out.println (nome [i]); }} */ ftpclient.enterlocalPassivEMode (); String [] name = ftpclient.listnames (file_regex) ;; if (nome == null) retorna nova string [0]; retornar this.sort (nome); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } retornar nova string [0]; } public void lists (string reg) {try {string [] a = ftpclient.listnames (reg); if (a! = null) {for (string b: a) {system.out.println (b); }}} catch (ioexception e) {// TODO BLOCO DE CATCH AUTOGERATION E.PRINTSTACKTRACE (); }} / ** * Defina o tipo do arquivo transferido [arquivo de texto ou arquivo binário] * * @param filetype * ---binary_file_type, ASCII_FILE_TYPE * / public void setFiletype (int filetype) {try {ftpclient.setFiletype (Filetype); } catch (ioexception e) {e.printStackTrace (); }}/ *** Arquivo de upload** @param localFilePath* -Caminho do arquivo local + Nome do arquivo* @param newFileName* -Nome do arquivo -novo*/ public void uploadFile (String LocalFilePath, string newFileName) {// upload this.ftpclient.ErtPasspalpalTemode (); tente {buffin = new bufferInputStream (new FileInputStream (localFilePath)); boolean ifupload = ftpclient.storeFile (newFileName, buffin); if (! ifupLoad) {System.out.println ("Carregar o arquivo falhou ..."); } else {System.out.println ("Carregue o arquivo com sucesso ..."); }} catch (Exceção e) {e.printStackTrace (); } finalmente {tente {if (buffin! = null) buffin.close (); } catch (Exceção e) {e.printStackTrace (); }}}/ ** * Arquivo de upload 2 * * @Param File * --FileInputStream Arquivo * @param newFileName * -Nome do arquivo -new */ public void newOUploadfile (arquivo de fileInpTream, string nameMode (); tente {buffin = new bufferInputStream (arquivo); boolean ifupload = ftpclient.storeFile (newFileName, buffin); if (! ifupload) {System.out.println ("Falha no arquivo de upload ..."); } else {System.out.println ("Faça o upload do arquivo com sucesso ..."); }} catch (Exceção e) {e.printStackTrace (); } finalmente {tente {if (buffin! = null) buffin.close (); } catch (Exceção e) {e.printStackTrace (); }}}/ ** * Baixar arquivo (single) * * @param remotefilename * -Nome do arquivo no servidor * @param localFileName * -Nome do arquivo -local */ public boolean DownloadFile (String RemoteFilename, string localFilename) {this.ftpclient.EsterLocalMode (String LocalEname) {this.ftppClient.ErtPasspalTemode (String LocalEname) {this.ftppClient.ErtPasspalpalMode (String LocalEname) {this.ftppClient.ErtPasspalpalMode; tente {buffout = new bufferoutputStream (new FileOutputStream (LocalFilename)); boolean ifdownload = ftpClient .retrievefile (remotefilename, buffout); if (! ifdownload) {System.out.println ("Falha no arquivo de download ..."); retornar falso; } else {System.out.println ("Baixar arquivo com sucesso ..."); }} catch (Exceção e) {e.printStackTrace (); retornar falso; } finalmente {tente {if (buffout! = null) buffout.close (); } catch (Exceção e) {e.printStackTrace (); }} retornar true; } / *** Feche a conexão FTP* / public void Close () {try {if (ftpClient! = Null) {ftpclient.logout (); ftpClient.disconnect (); }} catch (Exceção e) {e.printStackTrace (); }} / ** * String de classificação de bolhas (de grande a pequena) * / public String [] Sort (string [] str_array) {if (str_array == null) {lança new NullPointerException ("o str_array não pode ser nulo!"); } String tmp = ""; para (int i = 0; i <str_array.length; i ++) {for (int j = 0; j <str_array.length - i - 1; j ++) {if (str_array [j] .compareto (str_array [j+1]) <0) {tmp = str_array [j];; str_array [j] = str_array [j + 1]; str_array [j + 1] = tmp; }}} retornar str_array; } public static void main (string [] strs) {ftputil2 ftputil2 = new ftputil2 ("192.168.1.112", 20011, "test1", "test1", "/", true); Ftputil2.downloadfile ("test.txt", "d: //test.txt"); }}A seguir, a classe de ferramenta ZIP:
importar java.io.file; importar java.io.fileInputStream; importar java.io.fileOutputStream; importar java.io.ioException; importar java.io.inputStream; importar java.io.OutputStream; importar java.util.arraylist; importar java.util.enumeration; importar java.util.list; importar java.util.map; importar java.util.zip.zipentry; importar java.util.zip.zipfile; importar java.util.zip.zipOutputStream; importar org.apache.commons.io.ioutils; importação com.ibatis.common.logging.log; importar com.ibatis.common.logging.logfactory; classe pública ziputil {private static final log log = logFactory.getLog (ziputil.class); / *** Arquivo compactado** @param srcfile arquivo [] Lista de arquivos que precisam ser compactados* @param zipfile Arquivos Arquivos compactados*/ public static outputStream zipfiles (list <File> srcfile, outputStream OutputStream) {byte [] buf = novo byte [1024]; tente {// crie o arquivo zip zipOutputStream out = new ZipOutputStream (outputStream); // compacte os arquivos para (int i = 0; i <srcfile.size (); i ++) {arquivo file = srcfile.get (i); FileInputStream in = new FileInputStream (File); // Adicione a entrada ZIP ao fluxo de saída. out.putNextEntry (novo zipentry (file.getName ())); // transfira bytes do arquivo para o arquivo zip int len; while ((len = in.read (buf))> 0) { //System.out.println(len+"======================================================================================= ====================================================== doc ====================================================== doc ====================================================== doc e) {log.error ("Ziputil ZipFiles Exception:"+e); BYTE [1024]; Freqüência de saída. } catch (ioxception e) {log.error ("Ziputil ZipFiles Exception:"+e); zipfile) {tente {// Crie o arquivo zip zipOutputStream Out = new ZipOutputStream (new FileOutputStream (zipfile); FileEntry.getValue () Adicione a entrada de Zip no fluxo de saída. in.close (); * @param zipfile * @see */ public static void zipbyarray (map <string, byte []> srcfile, arquivo zipfile) {byte [] buf = new Byte [1024]; System.Println (srcfile.entryset (). Size ()); o arquivo para o arquivo zip [] bytes = FileEntry.getValue (); System.out.println (e.getMessage ()); para (entradas de enumeração = zf.entries (); entradas.hasmoreElements ();) {// Obtenha o nome de entrada Novo FileOutputStream (Descdir + ZipentryName); Log.error ("Ziputil UNZIPFILES EXCEÇÃO:" E); File (D: //2.jpg "); O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.