Java 버전의 Simple Cloud 앨범을 작성하면 구현 된 기능은 다음과 같습니다.
사용자는 한 번에 하나씩 여러 파일을 업로드 할 수 있습니다.
사용자는 다른 사람이 업로드 한 사진을 다운로드 할 수 있습니다.
사용자는 다른 사람의 사진을 볼 수 있습니다.
사용자는 자신의 IP를 통해 업로드 된 사진 만 삭제할 수 있습니다.
사용 된 기술 :
파일 업로드 및 다운로드, 디자인 모드, Dom4J, XPath 등
다음 두 페이지를 살펴 보겠습니다.
소스 코드 :
web.xml :
<? xml version = "1.0"encoding = "utf-8"?> <web-app version = "3.0"xmlns = "http://java.sun.com/xml/xml/ns/javaee"xmlns : xsi = "http://www.w3.org/2001/xmlschema-instance. xsi : schemalocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name> </display-name> <servlet> <servlet> uploadservlet </servlet-name> <Servlet-class> cn.hncu.servlets.uploadservlet </servlet-class> </servlet> <servlet> <servlet-name> CloudPhotoServlet </servlet-name> <servlet-class> cn.hncu.servlets.clhoToServlet </servlet-class> <servlet> <servlet> <servlet> <Servlet-Class> CN.hncu.servlets.downservlet </servlet-class> </servlet> <servlet> <servlet-name> delservlet </servlet-name> <servlet-class> cn.hncu.servlets.delservlet </servlets> </servlet> <servlet-mapping> <servlet-name> upload-name> <Url-pattern>/upload </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> cloudphotoServlet </servlet-name> <url-pattern>/cloudphoto </servlet-mapping> <servlet-mapping> <servlet-name> downservlet </servlet-name> downservlet> <Url-pattern>/servlet/downservlet </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> delservlet </servlet-name> <Url-pattern>/servlet/delservlet </url-pattern> </servlet-list> <Welcome-file> index.jsp </welcome-file> </welcome-file-list> </web-app>
index.jsp :
<%@ page language = "java"import = "java.util.*"pageencoding = "utf-8"%> <! doctype html public "-// w3c // dtd html 4.01 Transitional // en"> <html> <head> <title> chx 클라우드 앨범> <script type = "텍스트/javascrip. 표 = input.parentelement.parentelement.parentElement; // table.nodename tbody table.removechild (input.parentelement.parentelement); } var t = 1; 함수 addFile (입력) {tr = input.parentElement.parentElement; //alert(tr.nodename); var str = "<td>"</td> "+"<td> <input type = 'file'name = 'file "+ t+"'> </td> "+"<td> 파일 설명 : </td> "+"<td> <input type = 'text'name = 'text "+ t+"'> </td> "<td> <td> <td> <td> onclick = 'delfile (this)'> </td> "; tr.insertadjacenthtml ( "preverbegin", str); } 함수 move () {window.location.href = "/myphoto/cloudphoto"; } </script> <스타일 유형 = "text/css"> #font {color : 빨간색; } </style> </head> <body> <h1> <font id = "font"> 앨범 업로드 : </font> </h1> <양식 Action = "/myphoto/upload"method = "post"enctarpe = "multipart/form-data"> <table> <t> <td> </td> <td> <input = "file ="> <td> 파일 설명 : </td> <td> <입력 유형 = "text"name = "text1"> </td> <td> <입력 유형 = "버튼"value = "삭제 파일"Onclick = "delfile" "delfile (this)"> </td> </td> <td colspan = 2> <td valload ""upload ""upload ""upload ". colSpan = 3> <input type = "button"value = "파일 추가"onclick = "addfile (this)"> </td> </tr> </table> </form> <form> <form action = "/myphoto/cloudphoto"method = "enctype ="multipart/form-data "> <table> <tr> <td colspan = 5> onclick = "move ()"> </td> </tr> </table> </form> </body> </html>photo.xml :
<? xml 버전 = "1.0"encoding = "utf-8"?> <photos> </photos>
myutils.java :
패키지 cn.hncu.utils; import java.text.simpledateformat; import java.util.date; import java.util.uuid; public class myutils { / ** * @return get uuid * / public string getuuid () {return uuid.randomuuid (). " } / ** * @param uuid * @return uuid * / public static string getDir (String UUID) {String dir1 = integer.toHexString (uuid.hashCode () & 0xf); 문자열 dir2 = integer.tohexstring ((uuid.hashcode () & 0xf0) >> 4); 반환 "/"+dir1+"/"+dir2; } // 날짜 시간 형식 개인 정적 단순한 simpledateformat sdf = new SimpledateFormat ( "yyyyy 연도 mm 달 dd 날짜 hh : mm : ss"); / *** @return 업로드시 날짜와 시간을 반환합니다. }}dom4jfactory.java :
패키지 cn.hncu.utils; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.fileoutputStream; import java.io.ioexception; import java.io.unsupportedEncodingException; import org.dom4j.document; org org.documentection; org.dom4j.element; import org.dom4j.node; import org.dom4j.io.saxreader; import org.dom4j.io.xmlwriter; public class dom4jfactory {private static document dom = null; 개인 정적 문자열 경로; // 정적 블록! 한 번만 실행됩니다! 기능은 클래스가로드되면 static {saxreader sax = new SaxReader ()가 실행된다는 것입니다. // 우리의 리소스는 Myelipse에서 Tomcat 서버로 게시되었으므로 원래 Pure Java 프로젝트와 다릅니다. // 현재 클래스를 사용하여 클래스 로더를 찾은 다음 클래스 로더를 통해 리소스 경로를 얻습니다. path = dom4jfactory.class.getClassLoader (). getResource ( "photo.xml"). getPath (); // getClassLoader () 리턴 :이 개체로 표시되는 클래스 또는 인터페이스의 클래스 로더로드 // public url getResource (문자열 이름) 리턴 : 리소스의 URL 객체를 읽습니다. 리소스를 찾을 수 없거나 발신자가 리소스를 얻을 수있는 허가가 충분하지 않은 경우 NULL을 반환하십시오. //이 메소드는 먼저 리소스의 상위 클래스 로더를 검색합니다. 상위 클래스 로더가 NULL 인 경우 검색 경로는 가상 머신의 내장 클래스 로더의 경로입니다. // public String getPath ()는이 URL의 경로 부분을 가져옵니다. System.out.println (Path); dom = sax.read (new FileInputStream (Path)); } catch (filenotfoundException e) {throw new runtimeexception (e); } catch (DocumentException e) {throw new runtimeexception (e); }} / ** * @return 앨범의 문서를 가져옵니다 * / public static document getDocument () {return dom; } / ** * photo.xml을 저장하고 로컬 * / public static boolean save () {try {xmlwriter w = new xmlwriter (new FileoutputStream (path)); W.Write (dom); w.close (); 진실을 반환하십시오. } catch (UnsupportedEncodingException e) {return false; } catch (filenotfoundException e) {return false; } catch (ioexception e) {return false; }} public static boolean del (string uuid) {node node = dom.selectsingLenode ( "[@uuid = '"+uuid+"']"); if (node == null) {return false; } node.getParent (). 제거 (노드); 진실을 반환하십시오. } / *** test* @param args* / public static void main (String [] args) {system.out.println (getDocument ()); }}Photomodel.java- 값 객체
패키지 cn.hncu.domain;/*** 값 객체 캡슐화* @author Chen Haoxiang* 2016-7-24*/public class photomodel {private String uuid; // uuid private string realname = ""; // 그림의 실제 파일 이름 (private string); // private string; // private string; // private string; // 파일 업로드 개인 문자열 IP; // 업 로더의 IP 개인 문자열 desc; // 파일 설명 public String getUuid () {return uuid; } public void setUuid (String Uuid) {this.uuid = uuid; } public String getRealName () {return RealName; } public void setRealName (String realName) {this.RealName = realName; } public String getext () {return ext; } public void setext (String Ext) {this.ext = ext; } public String getDir () {return dir; } public void setdir (String dir) {this.dir = dir; } public String getDateTime () {return dateTime; } public void setDateTime (String dateTime) {this.dateTime = dateTime; } public String getIP () {return IP; } public void setip (String IP) {this.ip = ip; } public String getDesc () {return desc; } public void setdesc (String desc) {this.desc = desc; } @Override public String toString () {return "photomodel [uuid =" + uuid + ", realName =" + realName + ", ext =" + ext + ", dir =" + dir + ", dateTime =" + dateTime + ", ip =" + ip + ", desc =" + desc + "]; }}Photodao.java :
패키지 cn.hncu.photodao.dao; import java.util.list; import cn.hncu.domain.photomodel; public interface photodao { / *** @param photo* @return data* / public boolean save (photomodel photo); / *** @return 모든 그림 정보를 반환합니다*/ public list <photomodel> getall (); / *** @param uuid* @return uuid*/ public photomodel getsingleByuuid (String uuid)를 통해 캡슐화 된 값 객체를 찾습니다. / ** * @param uuid * @return uuid */ public boolean deletexml (string uuid)을 통해 photos.xml에서 이미지의 정보를 삭제합니다. / ** * @param dir * @return 경로를 통해 서버 디스크에서 이미지의 정보를 삭제하십시오 */ public boolean deletefile (String PathFilename);}photoserimpl.java :
패키지 cn.hncu.photodao.impl; import java.io.file; import java.util.arraylist; import java.util.iterator; import java.util.list; import org.dom4j.document; import org.dom4j.element; import org.dom4j.node; import org.dom4j.node; cn.hncu.photodao.dao.photodao; import cn.hncu.utils.dom4jfactory; public class photoserimpl은 photodao {@override public boolean save (photomodel photo) {document dom = dom4jfactory.getDocument (); 요소 root = dom.getRootElement (); // 속성 요소 p = root.addelement ( "photo") 추가; p.addattribute ( "uuid", photo.getUuid ()); p.addattribute ( "RealName", photo.getRealName ()); p.addattribute ( "dateTime", photo.getDateTime ()); p.addattribute ( "IP", photo.getIP ()); p.addattribute ( "ext", photo.getext ()); p.addattribute ( "dir", photo.getDir ()); p.addattribute ( "desc", photo.getDesc ()); return dom4jfactory.save (); } @override public list <photomodel> getall () {list <photomodel> list = new arraylist <photomodel> (); document dom = dom4jfactory.getDocument (); 요소 root = dom.getRootElement (); iterator <ementt> it = root.elementiterator ( "photo"); // dom4j를 통해 사진 요소의 반복자를 가져 오면 xpath를 통해 모든 사진을 찾을 수 있습니다. // list <node> lists = dom.selectnodes ( "// photo [@uuid]"); // iterator <Node> it = lists.iterator (); while (it.hasnext ()) {요소 e = it.next (); 광 도전 사진 = 새로운 포토 모드 (); photo.setuuid (e.attributeValue ( "uuid")); photo.setRealName (e.attributeValue ( "realName")); photo.setDateTime (e.attributeValue ( "dateTime")); photo.setext (e.attributeValue ( "ext")); photo.setip (e.attributeValue ( "IP")); photo.setdir (e.attributeValue ( "dir")); photo.setdesc (e.attributeValue ( "desc")); list.add (사진); } 반환 목록; } @override public photomodel getSulteByUuid (String UUID) {list <photomodel> photos = getall (); for (photomodel photo : photos) {if (photo.getUuid (). Equals (uuid)) {return photo; }} return null; } @override public boolean deletexml (string uuid) {document dom = dom4jfactory.getDocument (); 요소 e = (요소) dom.selectsingLenode ( "// photo [@uuid = '+uuid.trim ()+"'] "); return e.getParent (). 제거 (e); } @override public boolean deletefile (String pathfilename) {try {file file = 새 파일 (pathfilename); if (file.exists ()) {file.delete (); } true를 반환합니다. } catch (예외 e) {return false; }}}Photodaofactory.java :
패키지 cn.hncu.photodao.factory; import cn.hncu.photodao.impl.photoserimpl;/*** 팩토리 메소드* @author chen haoxiang* 2016-7-24*/public static photofactory {public static photoserimpl getphotodao () {return new photosmpl (); }}uploadservlet.java :
패키지 CN.hncu.servlets; import java.io.file; import java.io.ioexception; import java.io.printwriter; import java.util.list; import javax.servlet.servletexception; import javax.servlet.http.httpervlet; 가져 오기 javax.servlet.http.httpervletrequest; import javax.servlet.http.htttp.httpservletresponse; import org.apache.commons.fileupload.fileitem; import org.apache.commons.fileupload.fileuploadexception; import org.apache.commons.fileupload.disk.diskfileitemfactory; import org.apache.commons.fileupload.servlet.servletfileupload; import cn.hncu.domain.photomodel; import cn.hncu.photodao.dao.dao.dao.dao.photodao; cn.hncu.photodao.factory.photodaofactory; import cn.hncu.utils.dom4jfactory; import cn.hncu.utils.myutils; public class uploadservlet 확장 httpservlet {public void do (httpservletrequest responsk) strows strows, ii excence, ii excence Response.setContentType ( "Text/Html; charset = utf-8"); response.getWriter (). print ( "<h1> 죄송합니다.이 페이지는 액세스 할 수 없습니다 !!! </h1>"); response.getWriter (). print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아 가기 </a>"); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {response.setContentType ( "text/html; charset = utf-8"); 최종 인쇄기 out = response.getwriter (); // anti-black-non-multipart 양식 제출 // 업로드 도구 사용 부울 boo = servletfileupload.ismultipartContent (요청); if (! boo) {out.print ( "<h1>은 일반 양식의 제출 방법을 지원하지 않습니다! </h1>"); 반품; } file file = 새 파일 ( "d :/photocache"); if (! file.exists ()) {file.mkdir (); } diskFileItemFactory FifActory = New DiskFileItemFactory (1024*10, 파일); ServletFileUpload 업로드 = 새로운 ServletFileUpload (Fifactory); upload.setheaderEncoding ( "UTF-8"); // 파일 이름을 인코딩 문자열 경로 = getServletContext (). getRealPath ( "/photos"); fileItem fi = null; try {list <fileitem> list = upload.parserequest (요청); Photomodel photo = new Photomodel (); // 데이터 캡슐화 --- 7 특성이 필요합니다. int cont = 0; for (fileItem f : list) {if (cont! = 0 && cont%2 == 0 &&! photo.getRealName (). equals ( "")) {photo = new Photomodel (); // re-data acapsulation} fi = f; if (fi.isformfield ()) {// 일반 양식 구성 요소 // 파일 설명 GET get String desc = fi.getString ( "utf-8"); photo.setdesc (desc); //#1} else {// anti-black 3- 파일이 파일 구성 요소에서 선택되지 않은 경우 (fi.getSize () == 0) {photo.setRealName ( ""); cont ++; 계속하다; } 문자열 filename = fi.getName (); filename = filename.substring (filename.lastindexof ( "//")+1); // 실제 파일 이름 사진 .setRealName (filename); //#2 String ext = filename.substring (filename.lastindexof ( ")); // extension photo.setext (ext); //#3 photo.setDateMe (myUtils.getCurrentDateTime ()); //#4 photo.setip (request.getRemoteaddr ()); //#5 String uuid = myUtils.getUuid (); photo.setuuid (uuid); //#6 photo.setdir (myutils.getDir (uuid)); //#7 // 디렉토리 파일 dfile = 새 파일 (path+photo.getDir ()); if (! dfile.exists ()) {dfile.mkdir (); } fi.write (새 파일 (path+photo.getDir ()+"/"+photo.getUuid ()+photo.getext ())); } cont ++; if (cont%2 == 0 &&! photo.getRealName (). equals ( "")) {photodao dao = photodaofactory.getPhotodao (); boo = dao.save (사진); // 디스크에 저장 - 메소드 2 : fileUtils.copyInputStreamTofile (in, new File (filename2)); // ※ 2 ※ 이미지 파일을 서버 하드 디스크에 저장합니다. } catch (예외 e) {e.printstacktrace (); } 마침내 {if (fi! = null) {fi.delete (); } if (dom4jfactory.save ()) {out.print ( "<h1> 성공적으로 업로드! </h1>"); out.print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아 가기 </a>"); } else {out.print ( "<h1> 업로드 실패! </h1>"); out.print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아 가기 </a>"); }}}}모든 파일 표시 -Cloudphotoservlet.java
패키지 cn.hncu.servlets; import java.io.ioexception; import java.io.printwriter; import java.util.list; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.httplet.httpert.httpertreport javax.servlet.http.httpervletresponse; import cn.hncu.domain.photomodel; import cn.hncu.photodao.dao.photodao; import cn.hncu.photodao.photodao.photodaofactory; problphotosvlet extends httppervlet {problplet extends doget (httpservletrequest request, httpservletreponse response) servletexception, ioexception {string pwd = (string) request.getParameter ( "pwd"); if ( "chx".equals (pwd)) {dopost (요청, 응답); } else {response.setContentType ( "text/html; charset = utf-8"); Response.getWriter (). print ( "<H1> 죄송합니다. 액세스 권한이 없습니다 !!! </h1>"); }} public void dopost (httpservletrequest 요청, httpservletreponse 응답) servletexception, ioexception {response.setContentType ( "text/html; charset = utf-8"); printwriter out = response.getwriter (); out.println ( "<! doctype html public/"-// w3c // dtd html 4.01 Transitional // en/">"); out.println ( "<html>"); out.println ( "<head> <title> CHX 클라우드 앨범 </title> </head>"); out.println ( "<body>"); out.println ( "<테이블 테두리 = '1px; double;#ff0000'>"); out.println ( "<tr>"); out.println ( "<tr>"); out.println ( "<td> 파일 이름 </td>"); out.println ( "<td> 업로드 시간"); out.println ( "<td> 파일 </td>"); out.println ( "<td> 파일 설명 </td>"); out.println ( "<td> 작동 </td>"); out.println ( "</tr>"); 문자열 tdwh = "style = '너비 : 200px; 높이 : 200px;'"; // 모든 사진 표시 photodao dao = photodaofactory.getphotodao (); 목록 <photomodel> photos = dao.getall (); for (photomodel photo : photos) {String filename = photo.getRealName (); 문자열 시간 = photo.getDateTime (); // 출력 사진 문자열 경로 = request.getContextPath () + "/photos/" + photo.getDir () + "/" + photo.getUuid () + photo.getext (); // system.out.println (경로); ///myphoto/photos//7/c/a1237a48a6aa451cb22fa78b15bafcea.jpg String img = "<a href = '" + path + "> <img src =' + path +" '/> </a> "; 문자열 desc = photo.getDesc (); String delstr = "<a href = '/myphoto/servlet/delservlet? uuid =" + photo.getUuid () + "'> delete </a>"; 문자열 downstr = "<a href = '/myphoto/servlet/downservlet? uuid =" + photo.getUuid () + "'> 다운로드 </a>"; out.println ( "<td" + tdwh + ">" + filename + "</td>"); out.println ( "<td" + tdwh + ">" + time + "</td>"); out.println ( "<td" + tdwh + ">" + img + "</td>"); out.println ( "<td" + tdwh + ">" + desc + "</td>"); out.println ( "<td" + tdwh + ">" + delstr + "" + downstr + "</td>"); out.println ( "</tr>"); } out.println ( "<tr>"); out.println ( "</tr>"); out.println ( "</table>"); out.println ( "</body>"); out.println ( "</html>"); out.flush (); out.close (); }}파일 삭제 -Delservlet.java
패키지 cn.hncu.servlets; import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.htttp.httvletrequest; 가져 오기; javax.servlet.http.httpervletresponse; import cn.hncu.domain.photomodel; import cn.hncu.photodao.dao.photodao; import cn.hncu.photodao.photodao.photodaofactory; public spuredao tao httpervlet {// photodaofactory.getphotodao (); public void doget (httpservletrequest request, httpservletresponse 응답)은 servletexception, ioexception {dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {string uuid = request.getParameter ( "uuid"); 문자열 ip = request.getRemoteaddr (); Response.setContentType ( "Text/Html; charset = utf-8"); printwriter out = response.getwriter (); 광도 모델 사진 = dao.getSingleByUuid (uuid); if (photo! = null) {if (! photo.getip (). equals (ip)) {out.print ( "<h1>이 파일을 삭제할 권한이 없습니다!! </h1>"); out.print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아 가기 </a>"); 반품 ; } // 1. 데이터베이스에서 정보 삭제 부울 boo = dao.deletexml (uuid); if (boo) {String filename = "photos/"+photo.getDir ()+"/"+photo.getUuid ()+photo.getext (); String PathFilename = GetServletContext (). getRealPath (filename); if (dao.deletefile (pathfilename)) {// 앨범 페이지로 리디렉션. 응답 ( "/myphoto/cloudphoto? pwd = chx"); } else {out.print ( "<h1>은 서버에서 삭제할 수 없으며 파일이 점유됩니다 !!! </h1>"); out.print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아갑니다 </a>"); }} else {out.print ( "<h1> 파일이 더 이상 존재하지 않습니다 !!! </h1>"); out.print ( "<a href = 'javaScript : history.go (-1)'> 이전 페이지로 돌아갑니다 </a>"); }}}}파일 다운로드 -downservlet.java
패키지 cn.hncu.servlets; import java.io.fileInputStream; import java.io.ioException; import java.io.inputStream; import java.io.outputStream; import java.net.urlencoder; import javax.servlet.servletexception; import javax.servlet.htppervle javax.servlet.http.httpervletrequest; import javax.servlet.http.htttp.httpervletresponse; import cn.hncu.domain.photomodel; import cn.hncu.photodao.dao.photodao; import cn.hncu.photodao DownServlet은 httpservlet {private photodao dao = photodaofactory.getphotodao (); public void doget (httpservletrequest request, httpservletresponse 응답)은 servletexception, ioexception {dopost (요청, 응답); } public void dopost (httpservletRequest 요청, httpservletResponse 응답) servletexception, ioexception {string uuid = request.getParameter ( "uuid"); System.out.println (uuid); 광도 모델 사진 = dao.getSingleByUuid (uuid); System.out.println (사진); if (photo! = null) {// 응답 헤더를 설정합니다.-콘텐츠 수신기-브라우저 에서이 응답 헤더를 볼 때,이 응답 헤더를 열면 // (Thunder가 인식되는 경우, Thunder가 자동으로 열리지 않으면 "대화 상자가 열리지 않으면 STECTENTTYPE ("Application/Force-Donge "); 문자열 realName = photo.getRealName (); 문자열 agent = request.getheader ( "사용자 에이전트"); System.out.println (에이전트); if (agent.indexof ( "mozilla")! = -1) {// firefox 브라우저 응답 .setheader ( "content-disposition", "attachment; filename ="+ new String ( "realname.getBytes ("gb2312 ")),"iso-8859-1 "); } else {// garbled 중국어의 문제를 해결하십시오 (파일 이름을 인코딩하기 위해 다음 문장을 사용하십시오) realName = urlencoder.encode (realName, "UTF-8"); // 지정된 인코딩 메커니즘을 사용하여 문자열을 Application/X-ww-form-urlencoded 형식으로 변환하십시오. response.setHeader ( "내용화", "첨부 파일; filename =/" "+realName+"/""); // 참고 : "cttachment;" 누락 될 수 없으면 브라우저가 새 창에서 직접 열립니다.} string filename = "photos/"+photo.getDir ()+"/"+photo.getUuid ()+photo.getext (); String PathFilename = GetServletContext (). getRealPath (filename); inputStream in = new FileInputStream (PathFilename); outputStream out = response.getOutputStream (); 바이트 buf [] = 새로운 바이트 [2048]; int len = 0; while ((len = in.read (buf))! = -1) {out.write (buf, 0, len); } out.close (); 넣다(); } else {response.setContentType ( "text/html; charset = utf-8"); response.getWriter (). println ( "<h1>이 파일이 삭제되었습니다 </h1>"); }}}데모 결과
나는 이것을 보여주지 않을 것이며, 그 앞에는 사진이 있으며, 모든 소스 코드를 주었다. 관심이 있다면 스스로 개선 할 수 있습니다.
실제로, 이것은 보호 접미사 이름이 없기 때문에 다른 유형의 파일을 업로드 할 수 있으며, 캐릭터 스트리밍을 사용하여 전송하지 않으며 왜곡되지 않습니다 (클라우드 디스크 ~~로 처리 될 수 있음)! !
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.