คำนำ
เมื่อเร็ว ๆ นี้ฉันต้องโต้ตอบกับเซิร์ฟเวอร์ FTP ในโครงการของฉัน ฉันพบคลาสเครื่องมือเกี่ยวกับการอัปโหลดและดาวน์โหลด FTP บนอินเทอร์เน็ต มีประมาณสองประเภท
อย่างแรกคือคลาสรูปแบบซิงเกิล
ประเภทที่สองคือการกำหนดบริการอื่นซึ่งใช้การอัปโหลดและดาวน์โหลด FTP โดยตรงผ่านบริการ
ความรู้สึกทั้งสองนี้มีข้อดีและข้อเสีย
คนแรกใช้รหัสนำกลับมาใช้ซ้ำ แต่ต้องเขียนข้อมูลการกำหนดค่าในชั้นเรียนซึ่งมีความซับซ้อนมากขึ้นในการบำรุงรักษา
ประเภทที่สองคือ Framework Spring ข้อมูลการกำหนดค่าสามารถฉีดผ่านไฟล์คุณสมบัติ แต่รหัสไม่สามารถนำกลับมาใช้ใหม่ได้
ดังนั้นฉันวางแผนที่จะใช้คลาสเครื่องมือด้วยตัวเองเพื่อรวมข้อดีสองประการข้างต้น อย่างไรก็ตามปัญหาที่พบบ่อยในระหว่างกระบวนการอัปโหลดได้รับการแก้ไขเช่นกัน
เนื่องจากฉันใช้เฟรมเวิร์กสปริงหากคลาสเครื่องมือถูกประกาศว่าเป็นถั่วสำหรับการจัดการฤดูใบไม้ผลิมันเป็นซิงเกิลตันโดยค่าเริ่มต้นดังนั้นฉันไม่จำเป็นต้องใช้ซิงเกิลอีกครั้ง และเนื่องจากเป็นถั่วฉันจึงสามารถฉีดคุณสมบัติของไฟล์คุณสมบัติลงในคุณสมบัติของถั่วเพื่อแยกออกได้ ต่อไปนี้เป็นรหัสเฉพาะ:
แพ็คเกจ com.cky.util; นำเข้า java.io.file; นำเข้า java.io.fileoutputstream นำเข้า java.io.ioexception; นำเข้า java.io.inputstream; นำเข้า java.io.OutputStream; นำเข้า org.apache.Commons.net.ftp.ftp.ftp.ftp.ftp.ftp.ftp.ftp.ftp.ftp.ftp.ft org.apache.commons.net.ftp.ftpfile; นำเข้า org.apache.commons.net.ftp.ftpreply; นำเข้า org.springframework.beans.factory.annotation.value; นำเข้า org.springframework.stereotype.Component; {// การฉีดอัตโนมัติของ @Value ("$ {ftp.host}") โฮสต์สตริงส่วนตัว; // FTP Server IP @Value ("$ {ftp.port}") พอร์ต int ส่วนตัว; // พอร์ตเซิร์ฟเวอร์ ftp @value ("$ {ftp.username}") สตริงส่วนตัวชื่อผู้ใช้; // username @value ("$ {ftp.password}") รหัสผ่านสตริงส่วนตัว; // รหัสผ่าน @value ("$ {ftp.basepath}" ในวิธีหลักที่อยู่เบื้องหลังรหัส/*public ftputil () {//system.out.println (this.toString ()); host = "192.168.100.77"; พอร์ต = 21; ชื่อผู้ใช้ = "ftpuser"; รหัสผ่าน = "FTP54321"; basepath = "/home/ftpuser/"; }*// ************************************************************************************************ ลอง {ftp.connect (โฮสต์, พอร์ต); ftp.login (ชื่อผู้ใช้รหัสผ่าน); // ตั้งค่ารูปแบบการเข้ารหัสไฟล์ ftp.setControlencoding ("UTF-8"); // มีสองโหมดของการสื่อสาร FTP // พอร์ต (โหมดแอคทีฟ) เปิดพอร์ตใหม่ (> 1024) และส่งคำสั่งหรือส่งข้อมูลผ่านพอร์ตนี้ ในช่วงเวลานี้เซิร์ฟเวอร์ใช้พอร์ตเดียวที่เปิดขึ้นเช่น 21 // PASV (โหมดพาสซีฟ) ไคลเอนต์ส่งคำสั่ง PASV ไปยังเซิร์ฟเวอร์เซิร์ฟเวอร์จะเปิดพอร์ตใหม่ (> 1024) และใช้พอร์ตนี้เพื่อส่งข้อมูลกับพอร์ต 21 // เนื่องจากไคลเอนต์ที่ไม่สามารถควบคุมได้ // ตั้งค่าโหมดการส่งสัญญาณเป็นโหมดสตรีม ftp.setFileTransferMode (ftp.stream_transfer_mode); // รับรหัสสถานะเพื่อตรวจสอบว่าการเชื่อมต่อนั้นสำเร็จหรือไม่ถ้า (! ftpreply.ispositiveCompletion (ftp.getReplyCode ())) {โยน runtimeException ใหม่ ("เซิร์ฟเวอร์ FTP ปฏิเสธที่จะเชื่อมต่อ"); } // ไปที่ไดเรกทอรีรูทของไฟล์ที่อัปโหลดถ้า (! ftp.changeworkingDirectory (basepath)) {โยน runtimeException ใหม่ ("ไดเรกทอรีรากไม่มีอยู่ต้องสร้าง"); } // ตัดสินว่าไดเรกทอรีมีอยู่ถ้า (! ftp.changeworkingDirectory (เส้นทาง)) {String [] dirs = path.split ("/"); // สร้างไดเรกทอรีสำหรับ (สตริง dir: dirs) {ถ้า (null == dir || "". เท่ากับ (dir)) ดำเนินการต่อ; // ตัดสินว่าไดเรกทอรีมีอยู่ถ้า (! ftp.changeworkingDirectory (dir)) {// สร้าง if (! ftp.makedirectory (dir)) {โยน runtimeException ใหม่ ("การสร้างไดเรกทอรีย่อยล้มเหลว"); } // ป้อนไดเรกทอรีที่สร้างขึ้นใหม่ ftp.changeworkingDirectory (DIR); }} // ตั้งค่าประเภทไฟล์ที่อัปโหลดเป็นประเภทไบนารี ftp.setFileType (ftp.binary_file_type); // อัปโหลดไฟล์ถ้า (! ftp.storefile (ชื่อไฟล์, อินพุต)) {return false; } input.close (); ftp.logout (); กลับมาจริง; }} catch (exception e) {โยน runtimeException ใหม่ (e); } ในที่สุด {ถ้า (ftp.isconnected ()) {ลอง {ftp.disconnect (); } catch (ioexception e) {โยน runtimeException ใหม่ (e); }}} return false; } /** * * @param ชื่อไฟล์ชื่อไฟล์, หมายเหตุ! ชื่อไฟล์ที่นี่คือเส้นทางไฟล์ Plus Path เช่น: /2015/06/04/aa.jpg * @param LocalPath Store ที่ที่อยู่ท้องถิ่น * @return */Public Boolean ดาวน์โหลดไฟล์ (สตริงชื่อไฟล์สตริง localpath) {ftpClient ftp = new ftpClient (); ลอง {ftp.connect (โฮสต์, พอร์ต); ftp.login (ชื่อผู้ใช้รหัสผ่าน); // ตั้งค่ารูปแบบการเข้ารหัสไฟล์ ftp.setControlencoding ("UTF-8"); // มีสองโหมดของการสื่อสาร FTP // ไคลเอนต์พอร์ต (โหมดแอคทีฟ) เปิดพอร์ตใหม่ (> 1024) และส่งคำสั่งหรือส่งข้อมูลผ่านพอร์ตนี้ ในช่วงเวลานี้เซิร์ฟเวอร์ใช้พอร์ตเดียวที่เปิดขึ้นเช่น 21 // PASV (โหมดพาสซีฟ) ส่งคำสั่ง PASV ไปยังเซิร์ฟเวอร์เซิร์ฟเวอร์จะเปิดพอร์ตใหม่ (> 1024) และใช้พอร์ตนี้เพื่อส่งข้อมูลด้วยพอร์ตของลูกค้า 21 // จำเป็นต้องเปิดพอร์ตจากเซิร์ฟเวอร์ ftp.enterlocalPassiveMode (); // ตั้งค่าโหมดการส่งสัญญาณเป็นโหมดสตรีม ftp.setFileTransferMode (ftp.stream_transfer_mode); // รับรหัสสถานะเพื่อตรวจสอบว่าการเชื่อมต่อนั้นสำเร็จหรือไม่ถ้า (! ftpreply.ispositiveCompletion (ftp.getReplyCode ())) {โยน runtimeException ใหม่ ("เซิร์ฟเวอร์ FTP ปฏิเสธที่จะเชื่อมต่อ"); } int index = filename.lastindexof ("/"); // รับพา ธ ของพา ธ สตริงไฟล์ = filename.substring (0, ดัชนี); // รับชื่อสตริงชื่อไฟล์ = filename.substring (ดัชนี+1); // ตัดสินว่าไดเรกทอรีมีอยู่ถ้า (! ftp.changeworkingDirectory (basepath+path)) {โยน runtimeException ใหม่ ("เส้นทางไฟล์ไม่มีอยู่:"+basepath+path); } // รับไฟล์ทั้งหมดในไดเรกทอรีนี้ ftpfile [] ไฟล์ = ftp.listfiles (); สำหรับ (ไฟล์ ftpfile: ไฟล์) {// ตัดสินว่ามีไฟล์เป้าหมาย //system.out.println("File Name "+file.getName ()+" --- "+ชื่อ); if (file.getName (). เท่ากับ (ชื่อ)) {//system.out.println("file พบ "); // หากพบให้คัดลอกไฟล์เป้าหมายไปยังไฟล์ local localfile = ไฟล์ใหม่ (localPath+"/"+file.getName ()); outputStream out = new fileOutputStream (localFile); ftp.retrieveFile (file.getName (), ออก); out.close (); }} ftp.logout (); กลับมาจริง; } catch (exception e) {โยน runtimeException ใหม่ (e); } ในที่สุด {ถ้า (ftp.isconnected ()) {ลอง {ftp.disconnect (); } catch (ioexception e) {โยน runtimeException ใหม่ (e); }}}} // ถ้าใช้หนึ่งในสองฟังก์ชั่นอื่น ๆ จำเป็นต้องแสดงความคิดเห็นเกี่ยวกับโมฆะคงที่สาธารณะ (สตริง [] args) {// อัปโหลด ทดสอบ-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - E.PrintStackTrace (); } ในที่สุด {}*/// ดาวน์โหลด ทดสอบ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -การใช้งานเฉพาะ
ขั้นตอนที่ 1: กำหนดค่าสปริงเพื่อโหลดไฟล์คุณสมบัติ
ApplicationContext.xml
<บริบท: สถานที่ตั้งสถานที่ตั้งตำแหน่ง = "classpath:*. คุณสมบัติ"/> ftp.propertiesftp.host = 192.168.100.77ftp.port = 21ftp.username = ftpuserftp.password = ftp54321ftp.basepath =/home/ftpuser/ftpuser/ftpuser
ขั้นตอนที่ 2: ประกาศคลาสเครื่องมือเป็นถั่ว
วิธี XML
<bean id = "ftputil"> <property name = "host" value = "$ {ftp.host}"> </property> <property name = "พอร์ต" value = "$ {ftp.port}"> </property> <property name = "username" value = "$ {ftp.username}" value = "$ {ftp.password}"> </คุณสมบัติ> <property name = "basepath" value = "$ {ftp.basepath}"> </property> </ebean>วิธีการอธิบายประกอบการสแกนส่วนประกอบ
<บริบท: Component-Scan base-package = "com.cky.util"> </บริบท: Component-Scan>
ส่วนที่ 3: การฉีดและการใช้งาน
@autowired ftputil ftputil ส่วนตัว;
สรุป
ข้างต้นเป็นบทสรุปของปัญหาการอัปโหลดและการดาวน์โหลดเครื่องมือในฤดูใบไม้ผลิ FTP ที่แนะนำโดย Editor ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!