Recientemente, estoy haciendo un requisito: descargue el archivo que almacena la URL de la imagen del directorio FTP de otros sistemas, luego lea la dirección de URL en el archivo, descargue la imagen de acuerdo con la dirección y la comprime en un paquete en un día. En promedio, un archivo de dirección contiene aproximadamente 4,000 direcciones. Es decir, después de escanear un archivo, debe descargar alrededor de 4,000 imágenes y luego comprimirlo. El siguiente registra mi método de implementación y proceso de optimización. Si tiene alguna manera mejor, puede compartirlo.
Marco utilizado: SpringMVC
Implementación de la tarea cronometrada: heredar org.springframework.scheduling.quartz.quartzjobbean;
No hablaré sobre la construcción del entorno FTP. Lo he grabado en otros blogs que uso el servicio FTP creado por CentOS en la máquina virtual para crear una cuenta FTP y un directorio correspondiente, y cargue el archivo de dirección de imagen que debe descargarse con anticipación. Formato de contenido del archivo "ID de imagen || Dirección de imagen".
Método 1. La forma más fácil de implementarlo es descargar primero el archivo que almacena la dirección de URL de la imagen, luego leer el archivo que atraviesa la dirección de la imagen, ajustar el método de imagen descargado para almacenar la imagen localmente y finalmente comprimir la imagen descargada. Después de completar, elimine la imagen descargada y solo retenga el paquete comprimido.
La clase pública PictureTransferJob extiende Quartzjobbean {Protected void ExecuteInternal (JobExecutionContext Arg0) lanza JobExecutionException {// La configuración FTP real se obtiene leyendo el archivo de configuración // FTP Dirección String HostName = "192.168.1.112"; // FTP Port Int Port = 2001; /FTP Cuenta String UserName = "test1"; // ftp contraseña cadena contraseña = "test1"; // Directorio de almacenamiento de archivos FTP cadena ftpdowload = "/"; // La ruta de almacenamiento local de la ruta de cadena de archivo = this.getClass (). GetResource ("/"). GetPath (); // El directorio de almacenamiento de archivo de dirección de imagen cadena addrpath = path.substring (1, path.indexof ("webinf/classes"))+"picaddr"; // El directorio de almacenamiento de imágenes descargado real cadena picpath = path.substring (1, path.indexof ("webinf/classes"))+"pic"; addrpath = addrpath.replace ("%20", ""); Picpath = PicPath.replace ("%20", ""); Pruebe {// cree el archivo creatfile (addrpath); // Crear el archivo creatfile (PicPath); Cadena Oldaddrpath = addrpath; Cadena OldPicPath = PicPath; // Cree la conexión FTP FTPutil2 ftputil2 = new FTputIL2 (Nombre de host, puerto, nombre de usuario, contraseña, ftpdowload, true); // Transfiar el archivo en la cadena del directorio FTP [] archivos = ftputil2.ListallFiles (); // La base de datos local tendrá un registro de tabla de los archivos descargados. Aquí consultaremos la base de datos y los nombres de archivos enumerados en FTP. Si los archivos descargados no se descargarán y evite descargas repetidas. // El proceso de comparación se omite a continuación, enrleje la matriz de archivos y cree el archivo localmente para (int i = 0; i <files.length; i ++) {creatfile (addrpath+file.separator+filename); // ftpdowload es la dirección del servidor FTP para almacenar el archivo, AddRpath es la dirección del archivo de almacenamiento local // Aquí hay un estado de retorno para determinar si el archivo se descarga correctamente boolean downloadInvestFlag = ftputil2.downloadfile (ftpdowlowload, addRPath); // Un método para leer el archivo después de que el archivo se descarga correctamente, y la dirección de imagen que se descargará se almacena en el contenedor boolean entityState = setPicturedetail (addrpath, picpath, filenamedate); }} catch (Exception e) {E.PrintStackTrace (); // Haga clic en la clase ejecutiva que registra el registro de errores para enviar mensajes de texto que descarguen errores de archivo}} // Comience a leer la dirección de imagen aquí boolean privado setPicturedetail (string addrpath, string picpath, string sindate) { System.out.println("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- String row; int count = 0; addrmap.put (columna [0] .TRIM (), columna [1] .trim ()); System.out.println (nueva fecha ()); System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------------------------------------------------------------- E.PrintStackTrace (); FileName = NULL; UrlConnection se escribirá directamente en la matriz de bytes a través de InputStream y perderá datos, lo que resulta en imágenes descargadas incompletas. Los datos en la transmisión se leen en la matriz de bytes, y después de leer, los datos en la transmisión se borran PIC = nuevo archivo (PicPath+FileName+". JPG") Fos.CLOSE (); Zippic (PicPath, SyncDate, AdDRMap); {// Pausa en la lista de archivos que deben ser comprimidos y el nombre de archivo comprimido Ziputil.zipBystream (picList, nuevo archivo (PicPath+SynDate+". Zip")); if (! file.exists ()) {file.mkdirs (); Método 2: descarga multiproceso, compresión directa de transmisiones
Método 1 Aunque las funciones básicas se implementan, porque hay demasiadas imágenes que deben descargarse, y comprimir archivos de imágenes locales y eliminar imágenes también lleva mucho tiempo, por lo que hay dos lugares donde puede optimizar la velocidad. Una es mejorar la eficiencia de la descarga de imágenes, y la otra es mejorar la eficiencia de la compresión.
El método para mejorar la eficiencia de descarga puede usar descargas de múltiples subprocesos, y el método para mejorar la eficiencia de la compresión puede comprimir directamente la secuencia de archivos sin guardar la imagen localmente.
Método de implementación de múltiples subprocesos: Primero, guardamos la lista de direcciones de archivos que deben descargarse. Si queremos usar múltiples subprocesos para descargar, debemos asegurarnos de que las imágenes descargadas por diferentes hilos no se repitan. Por lo tanto, se necesita una bandera para distinguirlos. En este momento, podemos usar un contador índice para dividirlos de acuerdo con una cierta cantidad de imágenes descargadas por cada hilo. A partir de 0, cada 400 imágenes, podemos usar un hilo para descargar cada vez, para que podamos determinar la cantidad de hilos necesarios, y las imágenes descargadas por cada hilo no se repetirán.
Método de implementación de archivos comprimidos: Debido a que la esencia de generar archivos comprimidos es leer la transmisión de archivos que debe comprimirse, y luego generar un paquete comprimido, podemos usar el contenedor para almacenar los datos de la secuencia de imágenes descargados por todos los subprocesos en lugar de crear el archivo de imagen descargado y luego pasar los datos de flujo a la clase de herramientas de compresión para comprimirlo directamente. Esto omite el tedioso proceso de leer el archivo de imagen para crear la transmisión, luego generar el paquete comprimido y luego eliminar el archivo de imagen local.
Las principales implementaciones de la transformación se enumeran a continuación:
/ *** comprimir las imágenes descargadas por día* @throws ioException*/ private boolean zippic (string picpath, string sindate, map <string, string> addrmap) lanza ioexception {// ya que es una secuencia de imagen de almacenamiento multi-threadida, se necesita un mapa seguro de hilo, para que use mapcurrenthashmap <string, entrante> picturelista = nuevo nuevo flujo de imagen. Concurrenthashmap <string, inputStream> (); // El número de imágenes descargadas por cada hilo se define aquí int count = 400; // Almacenamiento La dirección de imagen que debe descargar la lista <Entry <String, String >> adDRList = new ArrayList <Entry <String, String >> (addRMap.EntrySet ()); // El número de hilos, agregue uno porque desea crear un hilo para descargar las últimas imágenes menos de 400 imágenes int nthreads = (addrlist.size ()/count) +1; // CountdownLatch CountdownLatch = new CountdownLatch (nThreads); intente {boolean downpic = false; // ejecutar múltiples imágenes de descarga downpic = downpic (PicPath, AdDRList, PicList, PictureList, NThreads, Count); if (downpic) {ziputil.zipbyArray (PicList, nuevo archivo (PicPath+Syncate+". Zip")); } return verdadero; } catch (Exception e) {E.PrintStackTrace (); devolver falso; }}Aquí está la creación de una piscina de hilo
/ *** Descargue la imagen de acuerdo con la dirección de la URL* @throws interrumpedException*/ private boolean downpic (string picpath, list <entry <string >> adrlist, map <string, byte []> picList, map <string, inputStream> PICTULIST, int nthread, int nthreads, INTO). threadpool = ejecutors.newFixedThreadPool (nthreads); // Crear dos contadores CountdownLatch begin = new CountdownLatch (0); CountDownLatch final = new CountdownLatch (nThreads); // bucle crea hilo para (int i = 0; i <nthreads; i ++) {list <Entry <string, string >> subaddrlist = null; // Calcule los datos ejecutados por cada hilo 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) * recuento; subaddrlist = addrlist.sublist (startIndex, endIndex); } // hilo class picdoDload myhead = nueva picdownload (PicPath, SubaddrList, PicList, PictureList); // La forma de ejecutar hilos aquí es llamar al método Threadpool.execute (Myhead) en el grupo de subprocesos. intente {threadpool.execute (myhead); } capt (excepción e) {// registro de error de error return false; }} begin.countDown (); end.await (); // Cierre la piscina de hilo Threadpool.shutdown (); // Aquí debe recorrer hasta que todos los hilos en la piscina de hilos hayan terminado antes de bajar. Debido a este paso durante la prueba, el hilo del niño descargó la imagen, pero no se ha completado, y el hilo principal ha disminuido, lo que no ha resultado en imágenes en el paquete comprimido // también puede usar CountdownLatch para implementar/*while (true) {if (threadPool.istermined ()) {System.out.println ("Todos los hilos infantiles han terminado!");; romper; }}*/ return true; }La siguiente es la implementación del hilo
class PicDownload implementos runnable {// Descargue la lista de direcciones de la lista de imágenes <Entrada <String, String >> addRList; // Cargue la lista de imágenes MAP DEL MAP <String, Byte []> PicList; Map <string, inputStream> pictureList; // La ruta de almacenamiento local de la cadena de imágenes PicPath; CountdownLatch comienza, final; public PicDownload (String PicPath, List <Entry <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 ()); Capacidad decepcionante (addrList); //System.out.println (CountdownLatch.getCount ()); begin.await (); } catch (Exception e) {E.PrintStackTrace (); } finalmente {end.countDown (); //countdownlatch.countdown (); }} public boolean Downpicture (List <Entry <String, String >> AdDRList) lanza la excepción {inputStream is = null; FileOutputStream fos = null; Url url = nulo; Cadena filename = null; Cadena picaddr = null; Archivo pic = null; Pruebe {for (map.entry <string, string> addrentry: addrlist) {filename = addRentry.getKey (); picaddr = addrentry.getValue (); // Crear el objeto URL url = new URL (PICADDR); es = url.openStream (); // La secuencia obtenida por UrlConnection se escribirá directamente en la matriz de bytes a través de InputStream y perderá datos, lo que dará como resultado imágenes descargadas incompletas. Use org.apache.commons.io.ioutils.tobytearray (urlconnection.openStream ()) para resolver // byte [] bytes = ioutils.tobytearray (is); // nuevo byte [is.available ()]; Los bytes obtenidos // Los datos en la secuencia se leen en la matriz de bytes. Después de leer, los datos en la transmisión se borrarán piclist.put (nombre de archivo+". Jpg", IS); // En este momento, dado que la transmisión no está escrita en el archivo, la transmisión no debe cerrarse, de lo contrario, los datos en la secuencia se perderán //is.close (); } return verdadero; } catch (Exception e) {E.PrintStackTrace (); devolver falso; } Finalmente {// La transmisión no se puede cerrar/*if (null! = is) {is.close (); }*/}}} Encontré otro problema usando transmisiones para la compresión arriba. Al comprimir el archivo, java.net.socketexception: restablecer la conexión
Después de analizar el motivo, debe ser que la transmisión de entrada y UrlConnection estén en el estado de conexión, y el restablecimiento del tiempo de espera de la contracción de urlConos hace que la secuencia de entrada no pueda obtener.
Traté de establecer el tiempo de tiempo de espera de UrlConnection, pero durante la prueba, descubrí que la velocidad de red de la descarga de imagen recibida se vio muy afectada. Este método es muy inestable e indeseable. Al final, solo dejé de usar la transmisión y usé una matriz de bytes para pasarla a la clase de herramienta de compresión, y luego convertí la matriz de bytes en la compresión de la corriente.
/ ***Use el contenedor para almacenar la matriz de bytes de imagen descargada*/ public boolean Downpicture (List <Entry <String, String >> AdDRList) lanza la excepción {inputStream is = null; FileOutputStream fos = null; Url url = nulo; Cadena filename = null; Cadena picaddr = null; Archivo pic = null; Pruebe {for (map.entry <string, string> addrentry: addrlist) {filename = addRentry.getKey (); picaddr = addrentry.getValue (); // Crear el objeto URL url = new URL (PICADDR); // Abra la conexión y cree el objeto java.net.urlconnection. Este objeto no tiene método para cerrar la conexión. Se puede convertir a su subclase httpurlconnection para llamar al método de desconexión para cerrar la conexión. //java.net.urlconnection y java.net.httpurlConnection ambos métodos de tiempo de espera establecidos para cerrar la conexión // httpurlconnection uc = (httpurlconnection) url.openconnection (); is = uc.getInputStream (); // La secuencia obtenida por UrlConnection se escribirá directamente en la matriz de bytes a través de InputStream y perderá datos, lo que dará como resultado imágenes descargadas incompletas. Use org.apache.commons.io.ioutils.tobytearray (urlconnection.openStream ()) para resolver byte [] bytes = ioutils.tobytearray (is); // new byte [is.available ()]; Los datos obtenidos // en la transmisión se leen en la matriz de bytes. Después de leer, los datos en la transmisión se borra //is.read(bytes); PicList.put (nombre de archivo+". jpg", bytes); is.close (); } return verdadero; } catch (Exception e) {E.PrintStackTrace (); devolver falso; } finalmente {if (null! = is) {is.close (); }}} Resumir:
Problemas encontrados durante la implementación:
1. Cuando se usa el grupo de subprocesos, para el estado compartido, por ejemplo, el contenedor de datos de bytes de imagen almacenado aquí es compartido por todos los hilos, por lo que se requiere un contenedor sincronizado, de lo contrario causará problemas con los datos almacenados. Por lo tanto, se usa concurrenthashmap <string, byte []>.
2. Hay un problema con el orden de ejecución del hilo principal y el hilo infantil aquí, porque el hilo principal debe esperar a que todos los hilos en el grupo de hilos terminen de descargar imágenes antes de bajar a las imágenes de comprimir. Si el hilo principal no espera a que el hilo infantil termine y ejecute el método de compresión hacia abajo, conducirá a imágenes comprimidas faltantes o no. Por lo tanto, puede usar CountDownLatch para implementarlo, o usar un bucle muerto para verificar ThreadPool.istermined () debajo de la instrucción de grupo de hilo de cierre para continuar ejecutando el hilo principal para comprimir la imagen.
3. Dado que el flujo de entrada obtenido por UrlConnection se transmite directamente a la clase comprimida para la compresión, hay una situación en la que el tiempo de espera de conexión se restablece, por lo que, en cambio, la transmisión descargada se almacena en una matriz de bytes y luego se pasa a la clase comprimida para comprimir para evitar situaciones inesperadas cuando se usa la corriente.
4. Después de usar URLConnection.OpenStream () Para obtener la secuencia de entrada, la imagen que convirtió en una matriz de bytes para descargar está incompleta. . Se puede resolver usando org.apache.commons.io.ioutils.tobytearray (urlconnection.openStream ()). Para más detalles, puede leer el código fuente para ver la implementación.
La siguiente es la implementación de la clase de herramienta FTP:
import java.io.bufferedInputStream; import java.io.bufferedOutputStream; import java.io.fileInputStream; import java.io.fileOutputStream; import java.io.ioException; importar org.apache.commons.net.ftp.ftpclient; importar org.apache.commons.net.ftp.ftpclientConfig; importar org.apache.commons.net.ftp.ftpconnectionClosedException; importar org.apache.commons.net.ftp.ftpreply; clase pública ftputil2 {private ftpClient ftpClient = null; // Dirección del servidor FTP Cadena privada HostName; // servidor FTP Port Port Public static int Defaultport = 21; // Nombre de inicio de sesión Nombre de usuario de cadena privada; // Inicie contraseña de contraseña de cadena privada contraseña; // directorio remoto para acceder a la cadena privada Remotedir; / ** * @Param HostName * Dirección de host * @param Port * Número de puerto * @param UserName * UserName * @param contraseña * contraseña * @param remotedir * directorio de trabajo predeterminado * @param is_zhtimezone * si es el lado del servidor ftp chino * @return * @return */ ** * nuevo método */ público ftputil2 () {propconfig Configuración = configuración PropConfig.LoadConfig ("System.Properties"); String hostName = config.getConfig ("ftpaddress"); String Port = config.getConfig ("ftpport"); String username = config.getConfig ("ftpusername"); Cadena contraseña = config.getConfig ("ftppassword"); String Remotedir = config.getConfig ("remotaFilePath"); boolean is_zhtimezone = true; this.hostname = hostname; this.Username = UserName; this.password = contraseña; this.remotedir = remotedir == nulo? "": Remotedir; this.ftpClient = new ftpClient (); if (is_zhtimitone) {this.ftpclient.configure (ftputil2.config ()); this.ftpclient.setControlEncoding ("gbk"); } // Acceso(); // cambiar el directorio this.changedir (this.remotedir); this.setFileType (ftpclient.binary_file_type); ftpClient.setDefaultPort (Integer.ParseInt (puerto)); } public ftputil2 (String HostName, int Port, String UserName, String Password, String Remotedir, Boolean IS_ZHTimAzone) {this.hostName = hostName; this.Username = UserName; this.password = contraseña; defaultport = puerto; this.remotedir = remotedir == nulo? "": Remotedir; this.ftpClient = new ftpClient (); if (is_zhtimitone) {this.ftpclient.configure (ftputil2.config ()); this.ftpclient.setControlEncoding ("gbk"); } // Iniciar sesión en this.login (); // cambiar el directorio this.changedir (this.remotedir); this.setFileType (ftpclient.ascii_file_type); ftpclient.setDefaultport (puerto); } / *** Inicie sesión en el servidor FTP* / public boolean login () {boolean éxito = falso; intente {ftpclient.connect (this.hostname, defaultport); ftpClient.login (this.username, this.password); int respuesta; respuesta = ftpClient.getReplyCode (); if (! ftPreply.ispositiveCompletion (respuesta)) {ftpClient.Disconnect (); devolver el éxito; }} Catch (ftpconnectionClosedException e) {// TODO Bloque de captura automática E.PrintStackTrace (); } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); } éxito = true; System.out.println ("Conecte al servidor FTP:" + this.hostname + "éxito..star inicio de sesión"); devolver el éxito; } private static ftpClientConfig config () {ftpClientConfig conf = new ftpClientConfig (ftpClientConfig.syst_unix); conf.setRecentDateFormatStr ("MM Month DD Fecha HH: MM"); // conf.setRecentDateFormatStr ("(año yyyy)? mm mes dd fecha (hh: mm)?"); devuelve conf; } / ** * Cambiar directorio de trabajo * * @param remotedir * * / public void cambiableir (string remotedir) {try {this.remotedir = remotedir; ftpClient.ChangeWorkingDirectory (remOTEDIR); } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); } System.out.println ("Cambie el directorio de trabajo a:" + remotedir); } / ** * Vuelva al directorio de nivel anterior (directorio principal) * / public void toparentDir () {try {ftpClient.ChangeToparentDirectory (); } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); }} / ***Enumere todos los archivos en el directorio de trabajo actual* / public String [] listAllFiles () {String [] names = this.listFiles ("*"); devolver esto.sort (nombres); } / ** * Lista de archivos de coincidencia en el directorio de trabajo especificado * * @param dir * exp: / cim / * @param file_regex * The Wildcard es * * / public String [] listAllFiles (String dir, string file_regex) {string [] names = this.listfiles (dir + file_regex); devolver esto.sort (nombres); } /** * Lista de archivos de coincidencia * * @param file_regex * caracteres de coincidencia, los caracteres Wildcard son * * /public string [] listFiles (string file_regex) {try { /** * ftpfile [] remotoFiles = ftpclient.listfiles (file_regex); * //System.out.println(remotefiles.length); String [] name = new * String [RemoteFiles.Length]; if (RemoteFiles! = NULL) {for (int * i = 0; i <remotafiles.length; i ++) {if (remotafiles [i] == null) * name [i] = ""; else * if (remotaFiles [i] .getName () == null || remotosfiles * [i] .getName (). Equals * (".") || RemoteFiles [i] .getName (). Equals ("..")) {nombre [i] = ""; *} más nombre [i] = RemoteFiles [i] .getName (); * System.out.println (nombre [i]); }} */ ftpClient.ENTERLOCALPASSIVEMODE (); String [] name = ftpclient.listNames (file_regex) ;; if (name == null) return nueva cadena [0]; devolver esto.sort (nombre); } Catch (Exception e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } devolver nueva cadena [0]; } public void lists (String reg) {try {string [] a = ftpclient.listNames (reg); if (a! = null) {for (cadena b: a) {system.out.println (b); }}} Catch (ioException e) {// tODO Auto Generado Bloque E.PrintStackTrace (); }} / ** * Establezca el tipo del archivo transferido [archivo de texto o archivo binario] * * @param fileType * - -binary_file_type, ascii_file_type * / public void setFileType (int filetype) {try {ftpClient.setFileType (filteType); } catch (ioException e) {E.PrintStackTrace (); }}/ *** Cargar archivo** @param localFilePath* --local File Path + File Name* @Param NewFileName* - -New File Name*/ public Void uploadFile (String localFilePath, string newFileName) {// upload este.ftpClient.Enterlocalpassivemode (// passive buffeDinEname buffeDinputterin intente {buffin = new BufferedInputStream (nuevo FileInputStream (LocalFilePath)); booleano ifupload = ftpclient.storeFile (newFileName, Buffin); if (! ifupload) {system.out.println ("cargar el archivo fallido ..."); } else {System.out.println ("cargue el archivo con éxito ..."); }} catch (Exception e) {E.PrintStackTrace (); } finalmente {try {if (buffin! = null) buffin.close (); } catch (Exception e) {E.PrintStackTrace (); }}}/ ** * Cargar archivo 2 * * @param archivo * -archivoinputstream archivo * @param newFileName * --new archivo de archivo */ public void newUploadFile (fileInputStream File, string newFileName) {// iba de archivo this.ftpClient.enterLocalpassIveMode (// MODECELEME PASSIVE BOFFINETINETINETINETINE = NTLULL; intente {buffin = new BufferedInputStream (archivo); booleano ifupload = ftpclient.storeFile (newFileName, Buffin); if (! ifupload) {system.out.println ("Cargar el archivo fallido ..."); } else {System.out.println ("Cargar el archivo con éxito ..."); }} catch (Exception e) {E.PrintStackTrace (); } finalmente {try {if (buffin! = null) buffin.close (); } catch (Exception e) {E.PrintStackTrace (); }}}/ ** * Descargar archivo (single) * * @param RemoteFileName * -Nombre de archivo en el servidor * @param localFileName * -Nombre de archivo -Local */ public boolean downloadFile (String RemoteFileName, String LocalFileName) {this.ftpClient.enterLocalpassIvemode (); // Passive Connection BuffeDutputPutiendoameMeMeMeMeMeLul intente {buffout = new BufferedOutputStream (nuevo FileOutputStream (localFileName)); boolean ifdownload = ftpClient .retrieveFile (remotoFileName, buffout); if (! ifdownload) {System.out.println ("Descargar el archivo fallido ..."); devolver falso; } else {System.out.println ("Descargar archivo con éxito ..."); }} catch (Exception e) {E.PrintStackTrace (); devolver falso; } finalmente {try {if (buffout! = null) buffout.close (); } catch (Exception e) {E.PrintStackTrace (); }} return verdadero; } / *** Cierre la conexión FTP* / public void Close () {try {if (ftpClient! = Null) {ftpClient.logout (); ftpclient.disconnect (); }} catch (Exception e) {E.PrintStackTrace (); }} / ** * String de clasificación de burbujas (de grande a pequeño) * / public string [] sort (String [] str_array) {if (str_array == null) {tire nueva nullpointerException ("El str_array no puede ser nulo!"); } Cadena tmp = ""; for (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; }}} return 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"); }}La siguiente es la clase de herramienta zip:
import java.io.file; import java.io.fileInputStream; import java.io.fileOutputStream; import java.io.ioException; import java.io.inputstream; import java.io.outputstream; import java.util.arrayList; importar java.util.enerumeration; import java.util.list; import java.util.map; import java.util.zip.zipentry; import java.util.zip.zipfile; import java.util.zip.zipoutputstream; importar org.apache.commons.io.ioutils; import com.ibatis.common.logging.log; import com.ibatis.common.logging.logFactory; public class Ziputil {private static final log = logFactory.getLog (ziputil.class); / *** Archivo comprimido** @param srcfile archivo [] Lista de archivos que deben comprimirse* @param Zipfile Archivo archivos comprimidos*/ public static outicStream ZipFiles (List <Schil> srcFile, outputStream outputStream) {byte [] buf = new byte [1024]; Pruebe {// cree el archivo zip ZipOutputStream out = new ZipOutputStream (outputStream); // comprimir los archivos para (int i = 0; i <srcfile.size (); i ++) {file file = srcfile.get (i); FileInputStream in = new FileInputStream (archivo); // Agregar entrada zip a la transmisión de salida. out.putNextEntry (new ZipEntry (file.getName ())); // transferir bytes desde el archivo al archivo zip int len; while ((len = in.read (buf))> 0) { //System.out.println(len+"======================================================================================= ================================================================================================================= ================================================================================================================= ================================================================================================================= e) {log.error ("excepción ziputil zipfiles:"+e); byte [1024]; STRIM. } catch (ioException e) {log.error ("excepción ziputil zipfiles:"+e); ZIPFILE) {try {// Crea el archivo zip ZipOutputStream Out = nuevo ZipOutputStream (nuevo FileOutputStream (ZIPFile)); fileEntry.getValue (); out.closeentry (); Archivo * @param srcfile * @param zipfile * @see */ public static void zipbyArray (map <string, byte []> srcfile, archivo zipfile) {byte [] buf = new byte [1024]; El system.out.println (srcfile.entryset (). size ()); Bytes del archivo al archivo zip byte [] bytes = fileEntry.getValue (); // ioutils.tobytearray (in); excepción: "+e); system.out.println (e.getMessage ());}} / *** unzip** @param archivo de archivo de archivo zipfile que debe descomponerse* @param descdir cadena descompresada directorio de destino* / public static void unzipfiles (archivo zipfile, string) {try {// ope the Zipfiles void void void void void (archivo Zipfile, string) {try {// abre el archivo ZIPFILES ZIPFILE ZIPFILE ZIPFILE ZIPFILE. ZipFile (ZipFile); System.Out.Println (ZipEndyName); out.close (); Archivo ("d: //1.jpg"); Ziputil.zipfiles (srcfile, zipfile); Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.