1、文件上传的核心点
1:用<input type=”file”/> 来声明一个文件域。File:_____ <浏览>.
2:必须要使用post方式的表单。
3:必须设置表单的类型为multipart/form-data.是设置这个表单传递的不是key=value值。传递的是字节码.
对于一个普通的表单来说只要它是post类型。默认就是
Content-type:application/x-www-from-urlencoded
表现形式
1:在request的请求头中出现。
2:在form声明时设置一个类型enctype="application/x-www-form-urlencoded";
如果要实现文件上传,必须设置enctype=“multipart/form-data”
表单与请求的对应关系:
2、如何获取上传的文件的内容-以下是自己手工解析txt文档
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 如果一个表单的类型是post且enctype为multipart/form-date * 则所有数据都是以二进制的方式向服务器上传递。 * 所以req.getParameter("xxx")永远为null。 * 只可以通过req.getInputStream()来获取数据,获取正文的数据 * * @author wangjianme * */ public class UpServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String txt = req.getParameter("txt");//返回的是null System.err.println("txt is :"+txt); System.err.println("========================================="); InputStream in = req.getInputStream(); // byte[] b= new byte[1024]; // int len = 0; // while((len=in.read(b))!=-1){ // String s = new String(b,0,len); // System.err.print(s); // } BufferedReader br = new BufferedReader(new InputStreamReader(in)); String firstLine = br.readLine();//读取第一行,且第一行是分隔符号 String fileName = br.readLine(); fileName = fileName.substring(fileName.lastIndexOf("\\")+1);// bafasd.txt" fileName = fileName.substring(0,fileName.length()-1); br.readLine(); br.readLine(); String data = null; //获取当前项目的运行路径 String projectPath = getServletContext().getRealPath("/up"); PrintWriter out = new PrintWriter(projectPath+"/"+fileName); while((data=br.readLine())!=null){ if(data.equals(firstLine+"--")){ break; } out.println(data); } out.close(); } }
3、使用apache-fileupload处理文件上传
框架:是指将用户经常处理的业务进行一个代码封装。让用户可以方便的调用。
目前文件上传的(框架)组件:
Apache----fileupload -
Orialiy – COS – 2008() -
Jsp-smart-upload – 200M。
用fileupload上传文件:
需要导入第三方包:
Apache-fileupload.jar – 文件上传核心包。
Apache-commons-io.jar – 这个包是fileupload的依赖包。同时又是一个工具包。
核心类:
DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个具类。
ServletFileUpload - 文件上传的核心类,此类接收request,并解析reqeust。
servletfileUpload.parseRequest(requdest) - List<FileItem>
一个FileItem就是一个标识的开始:---------243243242342 到 ------------------245243523452—就是一个FileItem
第一步:导入包
第二步:书写一个servlet完成doPost方法
/** * DiskFileItemFactory构造的两个参数 * 第一个参数:sizeThreadHold - 设置缓存(内存)保存多少字节数据,默认为10K * 如果一个文件没有大于10K,则直接使用内存直接保存成文件就可以了。 * 如果一个文件大于10K,就需要将文件先保存到临时目录中去。 * 第二个参数 File 是指临时目录位置 * */ public class Up2Servlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTf-8"); //获取项目的路径 String path = getServletContext().getRealPath("/up"); //第一步声明diskfileitemfactory工厂类,用于在指的磁盘上设置一个临时目录 DiskFileItemFactory disk = new DiskFileItemFactory(1024*10,new File("d:/a")); //第二步:声明ServletFileUpoload,接收上面的临时目录 ServletFileUpload up = new ServletFileUpload(disk); //第三步:解析request try { List<FileItem> list = up.parseRequest(req); //如果就一个文件 FileItem file = list.get(0); //获取文件名,带路径 String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("\\")+1); //获取文件的类型 String fileType = file.getContentType(); //获取文件的字节码 InputStream in = file.getInputStream(); //声明输出字节流 OutputStream out = new FileOutputStream(path+"/"+fileName); //文件copy byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ out.write(b,0,len); } out.close(); long size = file.getInputStream().available(); //删除上传的临时文件 file.delete(); //显示数据 resp.setContentType("text/html;charset=UTf-8"); PrintWriter op = resp.getWriter(); op.print("文件上传成功<br/>文件名:"+fileName); op.print("<br/>文件类型:"+fileType); op.print("<br/>文件大小(bytes)"+size); } catch (Exception e) { e.printStackTrace(); } } }
4、上传多个文件
第一步:修改页面的表单为多个input type=”file”
<form action="<c:url value='/Up3Servlet'/>" method="post" enctype="multipart/form-data"> File1:<input type="file" name="txt"><br/> File2:<input type="file" name="txt"><br/> <input type="submit"/> </form>
第二步:遍历list<fileitem>
public class Up3Servlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); //声明disk DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setSizeThreshold(1024*1024); disk.setRepository(new File("d:/a")); //声明解析requst的servlet ServletFileUpload up = new ServletFileUpload(disk); try{ //解析requst List<FileItem> list = up.parseRequest(request); //声明一个list<map>封装上传的文件的数据 List<Map<String,String>> ups = new ArrayList<Map<String,String>>(); for(FileItem file:list){ Map<String,String> mm = new HashMap<String, String>(); //获取文件名 String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("\\")+1); String fileType = file.getContentType(); InputStream in = file.getInputStream(); int size = in.available(); //使用工具类 FileUtils.copyInputStreamToFile(in,new File(path+"/"+fileName)); mm.put("fileName",fileName); mm.put("fileType",fileType); mm.put("size",""+size); ups.add(mm); file.delete(); } request.setAttribute("ups",ups); //转发 request.getRequestDispatcher("/jsps/show.jsp").forward(request, response); }catch(Exception e){ e.printStackTrace(); } } }
5、动态上传多个文件
核心问题:
在页面上应该可以控制<input type=”file”/>多少。
第一步:用table的格式化
<form name="xx" action="<c:url value='/Up3Servlet'/>" method="post" enctype="multipart/form-data"> <table id="tb" border="1"> <tr> <td> File: </td> <td> <input type="file" name="file"> <button onclick="_del(this);">删除</button> </td> </tr> </table> <br/> <input type="button" onclick="_submit();" value="上传"> <input onclick="_add();" type="button" value="增加"> </form> </body> <script type="text/javascript"> function _add(){ var tb = document.getElementById("tb"); //写入一行 var tr = tb.insertRow(); //写入列 var td = tr.insertCell(); //写入数据 td.innerHTML="File:"; //再声明一个新的td var td2 = tr.insertCell(); //写入一个input td2.innerHTML='<input type="file" name="file"/><button onclick="_del(this);">删除</button>'; } function _del(btn){ var tr = btn.parentNode.parentNode; //alert(tr.tagName); //获取tr在table中的下标 var index = tr.rowIndex; //删除 var tb = document.getElementById("tb"); tb.deleteRow(index); } function _submit(){ //遍历所的有文件 var files = document.getElementsByName("file"); if(files.length==0){ alert("没有可以上传的文件"); return false; } for(var i=0;i<files.length;i++){ if(files[i].value==""){ alert("第"+(i+1)+"个文件不能为空"); return false; } } document.forms['xx'].submit(); } </script> </html>
6、解决文件的重名的问题
import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; public class UpImgServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(1024*10,new File("d:/a")); ServletFileUpload up = new ServletFileUpload(disk); try{ List<FileItem> list = up.parseRequest(request); //只接收图片*.jpg-iamge/jpege.,bmp/imge/bmp,png, List<String> imgs = new ArrayList<String>(); for(FileItem file :list){ if(file.getContentType().contains("image/")){ String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("\\")+1); //获取扩展 String extName = fileName.substring(fileName.lastIndexOf("."));//.jpg //UUID String uuid = UUID.randomUUID().toString().replace("-", ""); //新名称 String newName = uuid+extName; FileUtils.copyInputStreamToFile(file.getInputStream(), new File(path+"/"+newName)); //放到list imgs.add(newName); } file.delete(); } request.setAttribute("imgs",imgs); request.getRequestDispatcher("/jsps/imgs.jsp").forward(request, response); }catch(Exception e){ e.printStackTrace(); } } }
7、处理带说明信息的图片
List<FileItem> :
FileItem:
|
|
|
|
|
|
getContentType() 获取文档的类型 |
||
getFieldName() 获取字段的名称,即name=xxxx <input type=”file” name=”img”/> |
||
getInputStream() |
||
getName() 获取文件名称。 如果是在IE获取的文件为 c:\aaa\aaa\xxx.jpg –即完整的路径。 非IE;文件名称只是 xxx.jpg |
||
|
|
|
long |
getSize() 获取文件大小 相当于in.avilivable(); |
|
如果你上传是一普通的文本元素,则可以通过以下方式获取元素中的数据 <form enctype=”multipart/form-data”> <input type=”text” name=”name”/> |
||
getString() 用于获取普通的表单域的信息。 |
||
getString(String encoding) 可以指定编码格式 |
||
void |
write(File file) 直接将文件保存到另一个文件中去。 |
|
以下文件用判断一个fileItem是否是file(type=file)对象或是text(type=text|checkbox|radio)对象: |
||
|
|
示例:
public class UpDescServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8");//可以获取中文的文件名 String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setRepository(new File("d:/a")); try{ ServletFileUpload up = new ServletFileUpload(disk); List<FileItem> list = up.parseRequest(request); for(FileItem file:list){ //第一步:判断是否是普通的表单项 if(file.isFormField()){ String fileName = file.getFieldName();//<input type="text" name="desc">=desc String value = file.getString("UTF-8");//默认以ISO方式读取数据 System.err.println(fileName+"="+value); }else{//说明是一个文件 String fileName = file.getName(); fileName = fileName.substring(fileName.lastIndexOf("\\")+1); file.write(new File(path+"/"+fileName)); System.err.println("文件名是:"+fileName); System.err.println("文件大小是:"+file.getSize()); file.delete(); } } }catch(Exception e){ e.printStackTrace(); } } }
8、目录打散-hash算法
会根据文件名计算一个目录出来,计算的这个目录必须是可再计算的。
原文件名为:你的相片.jpg
修改名称:8383902829432oiwowf.jpg
根据这个新的名称字符串,获取这个字符串的hash值 int hash = newName.hashCode();
hashCode =””+ 898987878;
获取后两位作为一个目录:78.
目录的个数:up/00-99/00-99 共100个目录
Up
01
01
..
99
02
..
99
import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * 处理目录打散。 * 思想:对新生成的文件名进行二进制运算。 * 先取后一位 int x = hashcode & 0xf; * 再取后第二位:int y = (hashCode >> 4) & 0xf; * @author wangjianme * */ public class DirServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setRepository(new File("d:/a")); try{ ServletFileUpload up = new ServletFileUpload(disk); List<FileItem> list = up.parseRequest(request); for(FileItem file:list){ if(!file.isFormField()){ String fileName = file.getName(); fileName=fileName.substring(fileName.lastIndexOf("\\")+1); String extName = fileName.substring(fileName.lastIndexOf(".")); String newName = UUID.randomUUID().toString().replace("-","")+extName; //第一步:获取新名称的hashcode int code = newName.hashCode(); //第二步:获取后一位做为第一层目录 String dir1 = Integer.toHexString(code & 0xf); //获取第二层的目录 String dir2 = Integer.toHexString((code>>4)&0xf); String savePath = dir1+"/"+dir2; //组成保存的目录 savePath=path+"/"+savePath; //判断目录是否存在 File f = new File(savePath); if(!f.exists()){ //创建目录 f.mkdirs(); } //保存文件 file.write(new File(savePath+"/"+newName)); file.delete(); //带路径保存到request request.setAttribute("fileName",dir1+"/"+dir2+"/"+newName); } } request.getRequestDispatcher("/jsps/show.jsp").forward(request, response); }catch(Exception e){ e.printStackTrace(); } } }
9、性能提升
核心点用FileItemIterator it= up.getItemIterator(request);处理文件上传。
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.RequestContext; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.commons.io.FileUtils; public class FastServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up"); DiskFileItemFactory disk = new DiskFileItemFactory(); disk.setRepository(new File("d:/a")); try{ ServletFileUpload up = new ServletFileUpload(disk); //以下是迭代器模式 FileItemIterator it= up.getItemIterator(request); while(it.hasNext()){ FileItemStream item = it.next(); String fileName = item.getName(); fileName=fileName.substring(fileName.lastIndexOf("\\")+1); InputStream in = item.openStream(); FileUtils.copyInputStreamToFile(in,new File(path+"/"+fileName)); } }catch(Exception e){ e.printStackTrace(); } } }
10、限制上传大小
1:限制总文件的大小 。 如 上传10文件,设置最多总上传大小为100M。
|
|
104857600
153046512
2:设置第每一个文件的大小 ,如果设置每 一个文件大小10M。
|
|
11、用COS实现文件上传
import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.oreilly.servlet.MultipartRequest; import com.oreilly.servlet.multipart.DefaultFileRenamePolicy; import com.oreilly.servlet.multipart.FileRenamePolicy; /** * 在Cos中就一个类, * MultipartRequest它是request的包装类。 */ public class CosServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { //第一步:声明文件的保存目录 String path = getServletContext().getRealPath("/up"); //第二步:文件传 //声明文件重新取名的策略 FileRenamePolicy rename = new DefaultFileRenamePolicy(); MultipartRequest req = new MultipartRequest(request,path,1024*1024*100,"UTF-8",new MyRename()); // //第三步:显示信息, resp.setContentType("text/html;charset=UTf-8"); PrintWriter out = resp.getWriter(); out.print("文件名称1:"+req.getOriginalFileName("img1")); out.print("<br/>新名称:"+req.getFilesystemName("img1")); out.print("<br/>类型1:"+req.getContentType("img1")); out.print("<br/>大小1:"+req.getFile("img1").length()); out.print("<br/>说明:"+req.getParameter("desc1")); if(req.getContentType("img1").contains("image/")){ out.print("<img src='"+request.getContextPath()+"/up/"+req.getFilesystemName("img1")+"'></img>"); } // out.print("<hr/>"); // out.print("文件名称2:"+req.getOriginalFileName("img2")); // out.print("<br/>类型2:"+req.getContentType("img2")); // out.print("<br/>大小2:"+req.getFile("img2").length()); // out.print("<br/>说明2:"+req.getParameter("desc2")); // // // out.print("<hr/>"); // out.print("文件名称3:"+req.getOriginalFileName("img3")); // out.print("<br/>类型3:"+req.getContentType("img3")); // out.print("<br/>大小3:"+req.getFile("img3").length()); // out.print("<br/>说明3:"+req.getParameter("desc3")); } } class MyRename implements FileRenamePolicy{ public File rename(File file) { String fileName = file.getName(); String extName = fileName.substring(fileName.lastIndexOf(".")); String uuid = UUID.randomUUID().toString().replace("-",""); String newName = uuid+extName;//abc.jpg file = new File(file.getParent(),newName); return file; } }
12、下载
即可以是get也可以是post。
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String name = req.getParameter("name"); //第一步:设置响应的类型 resp.setContentType("application/force-download"); //第二读取文件 String path = getServletContext().getRealPath("/up/"+name); InputStream in = new FileInputStream(path); //设置响应头 //对文件名进行url编码 name = URLEncoder.encode(name, "UTF-8"); resp.setHeader("Content-Disposition","attachment;filename="+name); resp.setContentLength(in.available()); //第三步:开始文件copy OutputStream out = resp.getOutputStream(); byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ out.write(b,0,len); } out.close(); in.close(); }
13、单线程断点下载
服务使用断点下载时,响应的信息是206。
UrlConnection - HttpurlConnection。-通过URL来获取urlconnection实例。
第一步:正常下载
import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; public class CommonDown { public static void main(String[] args) throws Exception { String path = "http://localhost:6666/day22_cos/up/video.avi"; URL url = new URL(path); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setDoInput(true); con.connect(); int code = con.getResponseCode(); System.err.println(code); if (code == 200) { //获取文件大小 long size = con.getContentLength(); System.err.println("总大小是:"+size); //声明下载到的字节 long sum=0; BigDecimal bd = new BigDecimal(0D); double already = 0D; InputStream in = con.getInputStream(); byte[] b = new byte[1024]; int len = -1; OutputStream out = new FileOutputStream("d:/a/video.avi"); while ((len = in.read(b)) != -1) { out.write(b, 0, len); sum=sum+len; double percent = ((double)sum)/((double)size); percent*=100; bd = new BigDecimal(percent); bd = bd.divide(new BigDecimal(1),0,BigDecimal.ROUND_HALF_UP); if(bd.doubleValue()!=already){ System.err.println(bd.intValue()+"%"); already=bd.doubleValue(); } } out.close(); } } }
第二步:断点下载
1:如何通知服务器只给我3以后数据。
req.setHeader("range","bytes=0-"); 从第0字节以后的所有字节
range=”bytes=3-”
2:我如何知道自己已经下载的3K数据。
读取文件大小。
file.length();
3:如果从当前已经下载的文件后面开始追加数据。
FileRandomAccess 随机访问文件对象
seek(long);
skip(long);
14、URLConnection
此类用于在java代码中模拟浏览器组成http协议向服务发请求(get/post)。
代码:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class OneServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { String name = request.getParameter("name"); System.err.println("这是get、、、、"+name); resp.setContentType("text/html;charset=UTF-8"); resp.getWriter().print("你好:"+name); } public void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); System.err.println("这是post请求......."+name); resp.setContentType("text/html;charset=UTF-8"); resp.getWriter().print("你好:"+name); } }
用urlconnection访问oneSerlvet
import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import org.junit.Test; public class Demo { /** * 发送get请求 * @throws Exception */ @Test public void testConn() throws Exception{ //第一步:声明url String urlPath = "http://localhost:6666/day22_cos/OneServlet?name=Jack"; //第二步:声明URL对象 URL url = new URL(urlPath); //第三步:从url上获取连接 HttpURLConnection con= (HttpURLConnection) url.openConnection(); //第四步:设置访问的类型 con.setRequestMethod("GET"); //第五步:设置可以向服务器发信息。也可以从服务器接收信息 con.setDoInput(true); //也可以从服务器接收信息 con.setDoOutput(true); //设置可以向服务器发信息 //第六步:连接 con.connect(); //7:检查连接状态 int code = con.getResponseCode(); if(code==200){ //8:从服务器读取数据 InputStream in = con.getInputStream(); byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ String s = new String(b,0,len,"UTF-8"); System.err.print(s); } } //9:断开 con.disconnect(); } /** * 以下发送post请求 */ @Test public void post() throws Exception{ //第一步:声明url String urlPath = "http://localhost:6666/day22_cos/OneServlet"; //第二步:声明URL对象 URL url = new URL(urlPath); //第三步:从url上获取连接 HttpURLConnection con= (HttpURLConnection) url.openConnection(); //第四步:设置访问的类型 con.setRequestMethod("POST"); con.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); //第五步:设置可以向服务器发信息。也可以从服务器接收信息 con.setDoInput(true);//设置可以向服务器发信息 con.setDoOutput(true);//也可以从服务器接收信息 //第六步:发信息 //获取输出流 OutputStream out = con.getOutputStream(); out.write("name=张三".getBytes("UTF-8")); //7:检查连接状态 int code = con.getResponseCode(); if(code==200){ //8:从服务器读取数据 InputStream in = con.getInputStream(); byte[] b = new byte[1024]; int len = 0; while((len=in.read(b))!=-1){ String s = new String(b,0,len,"UTF-8"); System.err.print(s); } } //9:断开 con.disconnect(); } }