最近、私は要件を作成しています。他のシステムのFTPディレクトリから画像URLを保存するファイルをダウンロードしてから、ファイルのURLアドレスを読み、アドレスに従って画像をダウンロードして、1日でパッケージに圧縮します。平均して、1つのアドレスファイルには約4,000のアドレスが含まれています。つまり、ファイルをスキャンした後、約4,000枚の写真をダウンロードしてから圧縮する必要があります。次の記録私の実装方法と最適化プロセスを記録します。より良い方法がある場合は、共有できます。
使用されるフレームワーク: SpringMVC
タイミングのタスクの実装:entert org.springframework.scheduling.quartz.quartzjobbean;
FTP環境の建設については話しません。 Virtual MachineでCentosによって構築されたFTPサービスを使用してFTPアカウントと対応するディレクトリを作成し、事前にダウンロードする必要がある画像アドレスファイルをアップロードすることを他のブログに記録しました。ファイルコンテンツフォーマット「画像ID ||画像アドレス」。
方法1.それを実装する最も簡単な方法は、最初に画像のURLアドレスを保存するファイルをダウンロードし、ファイルのトラバーサルを読み取り、ダウンロードした画像メソッドを調整して画像をローカルに保存し、最後にダウンロードした画像を圧縮することです。完了後、ダウンロードした画像を削除し、圧縮パッケージのみを保持します。
パブリッククラスのPictureTransferjobはQuartzJobbean {Protected void executeTernal(jobexecutioncontext arg0)Jobexecutionexceptionをスローする{//実際のftp構成は、構成ファイル// ftpアドレス文字列hostname = "192.168.1.12"; // ftp port int port = 2001; /ftpアカウント文字列username = "test1"; // ftpパスワード文字列パスワード= "test1"; // ftpファイルストレージディレクトリ文字列ftpdowload = "/"; //ファイル文字列パスのローカルストレージパス= this.getClass()。getResource( "/")。getPath(); //画像アドレスファイルストレージディレクトリ文字列addrpath = path.substring(1、path.indexof( "web-inf/classes"))+"picaddr"; //実際のダウンロードされた画像ストレージディレクトリ文字列picpath = path.substring(1、path.indexof( "web-inf/classes")+"pic"; addrpath = addrpath.replace( "%20"、 ""); picpath = picpath.replace( "%20"、 ""); try {//ファイルcreatfile(addrpath)を作成します; //ファイルcreatfile(picpath)を作成します。文字列oldaddrpath = addrpath;文字列oldpicpath = picpath; // ftp接続を作成しますftputil2 ftputil2 = new ftputil2(hostname、port、username、password、ftpdowload、true); // ftpディレクトリ文字列[] files = ftputil2.listallfiles()にファイルを送信します。 //ローカルデータベースには、ダウンロードされたファイルのテーブルレコードがあります。ここでは、FTPにリストされているデータベースとファイル名を照会します。ダウンロードされたファイルがダウンロードされない場合、繰り返しダウンロードを避けてください。 //比較プロセスを以下に省略し、ファイルアレイをループし、(int i = 0; i <files.length; i ++){creatfile(addrpath+file.separator+filename)の[int i = 0; i <files.length; i ++)のファイルを作成します。 // ftpdowloadはファイルを保存するFTPサーバーのアドレスです。AddRPATHはローカルストレージファイルのアドレスです//ここでは、ファイルがダウンロードされるかどうかを判断するリターンステータスです。 //ファイルが正常にダウンロードされた後にファイルを読み取る方法、ダウンロードする画像アドレスがContainer boolean entityState = setPictureDetail(Addrpath、Picpath、filenamedate)に保存されます。 }} catch(例外e){e.printstacktrace(); //エラーログを記録するビジネスクラスをクリックして、ファイルエラーをダウンロードするテキストメッセージを送信します}} //ここで画像アドレスを読み始めるprivate boolean setpictureDetail(string addrpath、string picpath、string syndate){ System.out.println("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- String row; int count = 0。 addrmap.put(0] .trim [1] .trim() System.out.println(new date()); System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- e.printstacktrace(); String Picaddr = null; InputStreamを介してバイトアレイは、ダウンロードされた画像を失います。アレイ、およびストリームのデータがクリアされた後、fos.write(pic); is.close(); zippic(picpath、syncdate、addrmap); {//圧縮されたファイル名ziputil.zipbystream(piclist、newファイル(Picpath+Syndate+"。Zip"。ZIP ") /*** @param Path* /private createf file(path); if(!file.exists()){file.mkdirs()}}}方法2:マルチスレッドダウンロード、ストリームの直接圧縮
方法1基本的な関数は実装されていますが、ダウンロードする必要がある写真が多すぎて、ローカル画像ファイルを圧縮して画像を削除することも時間がかかるため、速度を最適化できる2つの場所があります。 1つは写真のダウンロード効率を向上させることであり、もう1つは圧縮の効率を改善することです。
ダウンロード効率を改善する方法では、マルチスレッドダウンロードを使用でき、圧縮効率を改善する方法は、画像をローカルに保存せずにファイルストリームを直接圧縮できます。
マルチスレッド実装方法:最初に、ダウンロードする必要があるファイルのアドレスリストを保存します。マルチスレッドを使用してダウンロードしたい場合は、異なるスレッドでダウンロードされた写真が繰り返されないようにする必要があります。したがって、それらを区別するためにフラグが必要です。現時点では、インデックスカウンターを使用して、各スレッドからダウンロードされた一定量の写真に従ってそれらを分割できます。 0から400枚の画像ごとに、1つのスレッドを使用して毎回ダウンロードできます。これにより、必要なスレッドの数を決定できます。各スレッドでダウンロードされた写真は繰り返されません。
圧縮ファイルの実装方法:圧縮ファイルを生成するエッセンスは、圧縮する必要があるファイルストリームを読み取り、圧縮パッケージを生成することであるため、コンテナを使用して、ダウンロードされた画像ファイルを作成する代わりにすべてのスレッドでダウンロードした画像ストリームデータを保存し、ストリームデータを圧縮クラスに直接圧縮して通過できます。これにより、画像ファイルを読み取ってストリームを作成し、圧縮パッケージを生成し、ローカル画像ファイルを削除する退屈なプロセスが省略されます。
変換の主な実装は、以下にリストされています。
/ ***ダウンロードされた写真をDayで圧縮* @Throws IOException*/ Private Boolean Zippic(String Picpath、String Syndate、Map <String、String> addRMap)IoException {//はマルチスレッドストレージ画像ストリームであるため、スレッドセーフマップが必要なので、同時に使用します。 concurrenthashmap <string、inputstream>(); //各スレッドでダウンロードされた写真の数は、ここで定義されていますint count = 400; //ダウンロードする必要がある画像アドレス<エントリ<string、string >> addrlist = new arraylist <entry <string、string >>(addrmap.entryset()); //スレッドの数は、スレッドを作成して、最後の400未満の画像をダウンロードするためにスレッドを作成するために追加します。 // CountDownLatch CountDownLatch = new CountDownLatch(nthreads); try {boolean downpic = false; //マルチスレッドダウンロード写真ダウンピック=ダウンピック(ピクパス、addrlist、piclist、picturelist、nthreads、count); if(downpic){ziputil.zipbyarray(piclist、new file(picpath+syncate+"。zip")); } trueを返します。 } catch(Exception e){e.printstacktrace(); falseを返します。 }}こちらがスレッドプールの作成です
/ *** URLアドレスに従って画像をダウンロード* @Throws InternedException*/ Private Boolean Downpic(String Picpath、List <entry <entry <string、string >> addrlist、map <string、piclist、map <stramp、inputstream> picturelist、int nthreads、int count) ThreadPool = Executors.NewFixedThreadPool(nthreads); // 2つのカウンターを作成しますCountDownLatch begin = new CountDownLatch(0); CountDownLatch end = new CountDownLatch(nthreads); //ループfor(int i = 0; i <nthreads; i ++){list <entry <string、string >> subaddrlist = null; //各スレッドで実行されたデータを計算する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) * count; subaddrlist = addrlist.sublist(startindex、endindex); } //スレッドクラスpicdownload myhead = new picdownload(picpath、subaddrlist、piclist、picturelist); //ここでスレッドを実行する方法は、スレッドプールのスレッドプール(マイヘッド)メソッドを呼び出すことです。 try {threadpool.execute(myhead); } catch(例外e){// record error log return false; }} begin.countdown(); end.await(); //スレッドプールを閉じますthreadpool.shutdown(); //ここで、スレッドプール内のすべてのスレッドが終了する前に終了するまでループする必要があります。テスト中のこのステップにより、チャイルドスレッドは画像をダウンロードしましたが、メインスレッドがダウンしていないため、圧縮パッケージに写真がなくなりました// CountDownLatchを使用して/*を実装することもできます。壊す; }}*/ return true; }以下はスレッドの実装です
クラスのpicdownload runnable {//写真のアドレスリストをダウンロード<entry <string、string >> addrlist; //写真のリストをロードしました。 map <string、inputstream> picturelist; //画像文字列Picpathのローカルストレージパス。 CountDownLatchが始まり、終了します。パブリックピクダウンロード(String Picpath、List <Entry <entry <string、string >> addrlist、map <stram、inputstream> piclist、countdownlatch、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()); downpicture(addrlist); //system.out.println(countdownlatch.getCount()); begin.await(); } catch(Exception e){e.printstacktrace(); }最後に{end.countdown(); //countdownlatch.countdown(); }} public boolean downpicture(list <entry <entry <string、string >> addrlist)スロー{inputstream is = null; fileoutputStream fos = null; url url = null;文字列filename = null;文字列picaddr = null;ファイルpic = null; try {for(map.entry <string、string> addrentry:addrlist){filename = addrentry.getKey(); picaddr = addrentry.getValue(); // urlオブジェクトを作成しますurl = new url(picaddr); is = url.openstream(); // urlConnectionによって取得されたストリームは、inputStreamを介してバイト配列に直接記述され、データが失われ、ダウンロードされた画像が不完全になります。 org.apache.commons.io.ioutils.tobytearray(urlconnection.openstream())を使用して// byte [] bytes = ioutils.tobytearray(is); // new byte [is.abailable()];取得したバイト//ストリーム内のデータは、バイト配列に読み取られます。読み込んだ後、ストリーム内のデータがクリアされますpiclist.put(filename+"。Jpg"、is); //この時点で、ストリームはファイルに書き込まれないため、ストリームを閉じてはなりません。そうしないと、ストリーム内のデータが失われます//is.close(); } trueを返します。 } catch(Exception e){e.printstacktrace(); falseを返します。 }最後に{//ストリームを閉じることはできません/*if(null!= is){is.close(); }*/}}}上記の圧縮にストリームを使用して別の問題に遭遇しました。ファイルを圧縮するとき、java.net.socketexception:接続リセット
理由を分析した後、Stream InputStreamとUrlConnectionが接続状態にあるはずであり、URLConnection Timeoutリセットにより、入力ストリームが取得されなくなります。
UrlConnectionのタイムアウト時間を設定しようとしましたが、テスト中に、受信した画像ダウンロードのネットワーク速度が大きく影響を受けることがわかりました。この方法は非常に不安定で望ましくありません。最終的に、私はストリームを使用するだけであきらめ、バイト配列を使用して圧縮ツールクラスに渡し、バイト配列を変換して圧縮をストリーミングしました。
/ ***コンテナを使用してダウンロードした画像バイト配列を保存します*/ public boolean downpicture(list <entry <string、string >> addrlist)スロー例外{inputstream is = null; fileoutputStream fos = null; url url = null;文字列filename = null;文字列picaddr = null;ファイルpic = null; try {for(map.entry <string、string> addrentry:addrlist){filename = addrentry.getKey(); picaddr = addrentry.getValue(); // urlオブジェクトを作成しますurl = new url(picaddr); //接続を開き、java.net.urlconnectionオブジェクトを作成します。このオブジェクトには、接続を閉じる方法はありません。サブクラスのhttpurlconnectionに変換して、接続メソッドを呼び出して接続を閉じることができます。 //java.net.urlconnectionおよびjava.net.httpurlconnectionの両方が接続を閉じるためのタイムアウトメソッドを設定しますis = uc.getInputStream(); // urlConnectionによって取得されたストリームは、inputStreamを介してバイト配列に直接記述され、データが失われ、ダウンロードされた画像が不完全になります。 org.apache.commons.io.ioutils.tobytearray(urlconnection.openstream())を使用して、byte [] bytes = ioutils.tobytearray(is); // new byte [is.abable()];取得したバイト//ストリーム内のデータは、バイト配列に読み取られます。読み込んだ後、ストリーム内のデータがクリアされます//is.read(bytes); piclist.put(filename+"。jpg"、bytes); is.close(); } trueを返します。 } catch(Exception e){e.printstacktrace(); falseを返します。 }最後に{if(null!= is){is.close(); }}}要約:
実装中に遭遇する問題:
1.たとえば、共有状態でスレッドプールを使用する場合、ここに保存されている画像バイトデータコンテナはすべてのスレッドで共有されるため、同期コンテナが必要です。そうしないと、保存されたデータに問題が発生します。したがって、concurrenthashmap <string、byte []>が使用されます。
2。メインスレッドと子スレッドの実行順序には問題があります。メインスレッドは、スレッドプール内のすべてのスレッドが画像のダウンロードを終了する前に画像を圧縮するためにダウンロードを終了する必要があるためです。メインスレッドが子スレッドが終了するのを待たず、圧縮方法を下に実行すると、圧縮画像の欠落がないか、不足していません。したがって、CountDownLatchを使用してそれを実装するか、Dead Loopを使用してThreadPool.Istrimated()を閉じたスレッドプールステートメントの下で確認して、メインスレッドを実行して画像を圧縮し続けることができます。
3. URLConnectionによって取得された入力ストリームは圧縮のために圧縮クラスに直接送信されるため、接続タイムアウトがリセットされる状況があるため、代わりにダウンロードされたストリームがバイト配列に保存され、圧縮クラスに渡されて、ストリームを使用するときの予期しない状況を回避するために圧縮されます。
4。urlconnection.openstream()を使用して入力ストリームを取得した後、ダウンロードするためにバイト配列に変換した画像は不完全です。 。 org.apache.commons.io.ioutils.tobytearray(urlconnection.openstream())を使用して解決できます。詳細については、ソースコードを読んで実装を表示できます。
以下は、FTPツールクラスの実装です。
java.io.bufferedinputStreamをインポートします。 java.io.bufferedOutputStreamをインポートします。 java.io.fileinputStreamをインポートします。 java.io.fileoutputStreamをインポートします。 java.io.ioexceptionをインポートします。 Import org.apache.commons.net.ftp.ftpclient; org.apache.commons.net.ftp.ftpclientconfigをインポートします。 import org.apache.commons.net.ftp.ftpconnectionclosedexception; import org.apache.commons.net.ftp.ftpreply; public class ftputil2 {private ftpclient ftpclient = null; // ftpサーバーアドレスプライベート文字列ホスト名。 // ftpサーバーデフォルトポートpublic static int defaultport = 21; //ログイン名プライベート文字列ユーザー名。 //パスワードのプライベート文字列パスワードをログインします。 //プライベート文字列remotedirにアクセスするリモートディレクトリ。 / ** * @param hostname * hostアドレス * @paramポート *ポート番号 * @param username * username * @paramパスワード *パスワード * @param remotedir * @param remotedir * @param is_zhtimezone *中国のFTPサーバー側 * @return * @return */ ** *新しい方法 */ public ftputil2 propconfig.loadconfig( "System.Properties"); string hostname = config.getConfig( "ftpaddress"); string port = config.getConfig( "ftpport"); string username = config.getConfig( "ftpusername");文字列パスワード= config.getConfig( "ftppassword"); string remotedir = config.getConfig( "remotefilepath"); boolean is_zhtimezone = true; this.hostname = hostname; this.username = username; this.password = password; this.remotedir = remotedir == null? "":Remotedir; this.ftpclient = new ftpclient(); if(is_zhtimezone){this.ftpclient.configure(ftputil2.config()); this.ftpclient.setControlencoding( "gbk"); } // ログイン(); //ディレクトリを切り替えますthis.changedir(this.remotedir); this.setfiletype(ftpclient.binary_file_type); ftpclient.setDefaultPort(integer.parseint(port)); } public ftputil2(string hostname、int port、string username、string password、string remotedir、boolean is_zhtimezone){this.hostname = hostname; this.username = username; this.password = password; defaultport = port; this.remotedir = remotedir == null? "":Remotedir; this.ftpclient = new ftpclient(); if(is_zhtimezone){this.ftpclient.configure(ftputil2.config()); this.ftpclient.setControlencoding( "gbk"); } // this.login()にログインします。 //ディレクトリを切り替えますthis.changedir(this.remotedir); this.setfiletype(ftpclient.ascii_file_type); ftpclient.setDefaultPort(ポート); } / *** ftpサーバーにログイン* / public boolean login(){boolean success = false; try {ftpclient.connect(this.hostname、defaultport); ftpclient.login(this.username、this.password); int返信; REPLY = FTPCLIENT.GETREPLYCODE(); if(!ftpreply.ispositiveCompletion(reply)){ftpclient.disconnect();成功を返す; }} catch(ftpconnectionClosedException e){// todo auto-fenated catch block e.printstacktrace(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); } success = true; system.out.println( "ftpサーバーへの接続:" + this.hostname + "success..Startログイン");成功を返す; } private static ftpclientconfig config(){ftpclientconfig conf = new ftpclientconfig(ftpclientconfig.syst_unix); conf.setrecentDateFormatstr( "mm month dd date hh:mm"); // conf.setRecentDateFormatstr( "(yyyyy year)?mm month dd date(hh:mm)?"); confを返します。 } / ** *ワーキングディレクトリの変更 * * @param remotedir * * / public void chandedir(string remotedir){try {this.remotedir = remotedir; ftpclient.changeworkingdirectory(remotedir); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); } system.out.println( "作業ディレクトリを次のように変更します。" + remotedir); } / ** *前のレベルディレクトリ(親ディレクトリ)に戻ります * / public void toparentdir(){try {ftpclient.changetoparentdirectory(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }} / ***現在の作業ディレクトリのすべてのファイルをリスト* / public string [] listallfiles(){string [] names = this.listfiles( "*"); this.sort(names); } / ** *指定されたワーキングディレクトリの一致ファイルのリスト * * @param dir * exp: / * @param file_regex *ワイルドカードは * * * / public string [] listallfiles(string dir、string file_regex){] names = this.listfiles(dir + file_regex); this.sort(names); } /** *マッチングファイルのリスト * * @param file_regex *マッチ文字、ワイルドカード文字は * * /public string [] listfiles [] listfiles(string file_regex){try { /** * ftpfile [] remotefiles = ftpclient.listfiles(file_regex); * //system.out.println(remotefiles.length); string [] name = new * string [remotefiles.length]; if(remotefiles!= null){for(int * i = 0; i <remotefiles.length; i ++){if(remotefiles [i] == null) * name [i] = ""; else * if(remotefiles [i] .getname()== null || remotefiles * [i] .getname()。equals *( "。")|| remotefiles [i] .getname()。 *} else name [i] = remotefiles [i] .getname(); * System.out.println(name [i]); }} */ ftpclient.enterlocalpassivemode(); string [] name = ftpclient.listnames(file_regex);; if(name == null)新しい文字列[0]を返します。 this.sort(name); } catch(例外e){// todo auto-enerated catch block e.printstacktrace(); }新しい文字列[0]を返します。 } public void list(string reg){try {string [] a = ftpclient.listnames(reg); if(a!= null){for(string b:a){system.out.println(b); }}} catch(ioexception e){// todo auto-enerated catch block e.printstacktrace(); }} / ** *転送されたファイルのタイプ[テキストファイルまたはバイナリファイル] * * @param filetype * - binary_file_type、ascii_file_type * / public void setfiletype(int filetype){try {ftpclient.setfiletype(filetype); } catch(ioexception e){e.printstacktrace(); }}/ ***アップロードファイル** @param localfilepath* - ローカルファイルパス +ファイル名* @param newfilename* - new file name*/ public void uploadfile(string localfilepath、string newfilename){// upload file this.ftpclient.enterlocalpassivemode(); try {buffin = new BufferedInputStream(new fileInputStream(localfilepath)); boolean ifupload = ftpclient.storefile(newfilename、buffin); if(!ifupload){system.out.println( "ファイルが故障したアップロード..."); } else {system.out.println( "ファイルを正常にアップロード..."); }} catch(例外e){e.printstacktrace(); }最後に{try {if(buffin!= null)buffin.close(); } catch(Exception e){e.printstacktrace(); }}}/ ** * file 2 * * @param file * - fileinputstream file * @param newfilename * - new file name */ public void newuploadfile(fileinputStream file、string newfileName){//ファイルをアップロードするfile this.ftpclient.enterlocalpassivemodemodemodemodemodemodemodemodemodinupt; try {buffin = new BufferedInputStream(file); boolean ifupload = ftpclient.storefile(newfilename、buffin); if(!ifupload){system.out.println( "file failed ..."); } else {system.out.println( "ファイルを正常にアップロード..."); }} catch(例外e){e.printstacktrace(); }最後に{try {if(buffin!= null)buffin.close(); } catch(Exception e){e.printstacktrace(); }}}/ ** * file(single) * * @param remotefilename * - serverのファイル名 * @param localfilename * - local file name * - public boolean downloadfilename(string remotefilename、string localfilename){this.ftpclient.enterlocalpassivemode(); try {buffout = new BufferedOutputStream(new FileOutputStream(localFileName)); boolean ifdownload = ftpclient .retrievefile(remotefileName、buffout); if(!ifdownload){system.out.println( "ファイルのダウンロード障害..."); falseを返します。 } else {system.out.println( "ファイルを正常にダウンロード..."); }} catch(例外e){e.printstacktrace(); falseを返します。 }最後に{try {if(buffout!= null)buffout.close(); } catch(Exception e){e.printstacktrace(); }} trueを返します。 } / *** ftp接続を閉じる* / public void close(){try {if(ftpclient!= null){ftpclient.logout(); ftpclient.disconnect(); }} catch(例外e){e.printstacktrace(); }} / ** *バブルソート文字列(大部分から小さい) * / public string [] sort(string [] str_array){if(str_array == null){throw new nullpointerexception( "str_arrayはnull!"); }文字列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] .comareto(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"); }}以下はzipツールクラスです。
java.io.fileをインポートします。 java.io.fileinputStreamをインポートします。 java.io.fileoutputStreamをインポートします。 java.io.ioexceptionをインポートします。 java.io.inputStreamをインポートします。 java.io.outputStreamをインポートします。 java.util.arraylistをインポートします。 java.util.numerationをインポートします。 java.util.listをインポートします。 java.util.mapをインポートします。 java.util.zip.zipentryをインポートします。 java.util.zip.zipfileをインポートします。 java.util.zip.zipoutputStreamをインポートします。 org.apache.commons.io.ioutilsをインポートします。 com.ibatis.common.logging.logをインポートします。 com.ibatis.common.logging.logfactoryをインポートします。 public class ziputil {private static final log = logfactory.getlog(ziputil.class); / ***圧縮ファイル** @param srcfileファイル[]圧縮する必要があるファイルのリスト* @param zipfileファイル圧縮ファイル*/ public static outputstream zipfiles(list <file> srcfile、outputstream outputstream){byte [] buf = new byte [1024]; try {// zipファイルを作成zipoutputStream out = new zipoutputStream(outputStream); //(int i = 0; i <srcfile.size(); i ++){file file = srcfile.get(i); fileInputStream in = new fileInputStream(file); // zipエントリを出力ストリームに追加します。 out.putnextentry(new Zipentry(file.getName())); //ファイルからzipファイルint lenにバイトを転送します。 while((len = in.read(buf))> 0){ //system.out.println(len+"==================================================================================================================== ========================================================================================================== ========================================================================================================== ========================================================================================================== e){log.error( "ziputil zipfiles例外:"+e); BYTE [1024] {// zipoutputStream(new fileoutputStream(zipfile))を作成します出力ストリーム(file.getName()); } catch(ioexception e){log.error( "ziputil zipfiles例外:"+e); zipfile){// zip file zipoutputstream out = new fileoutputstream(zipfile)); fileEntry.getValue(); out.closeEntry(); @param srcfile * @param zipfile */ public static void zipbyarray(map <string []> srcfile、file zipfile){] buf = new byte [1024]; system.out.println()size()); zip file bytes = fileEntry.getValue(// ioutil.close); System.out.println(e.getMessage());} / **** @param zipfileファイルファイルファイルファイルファイルを解凍します* / param zipfile(zipfile); System.Out.Println(scdir + zipentryname); out.close(); catch(ioexception e){ziputil unzipfiles: "+e) file(d://1.jpg "); srcfile.add(" d://3.jpg "); ziputil.zipfiles(srcfile、zipfile);上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。