QUESTION:fileUpload组件原理和实现

ANSWER:

目录

QUESTION:fileUpload组件原理和实现

ANSWER:

一:异常产生

查询了一系列博客后,发现这是由于上传文件的大小超过了可以上传的临时文件限制。

二:fileUpload组件及Java Web中文件上传的原理方法

2.1基本原理

2.2实现代码

2.3重要方法

2.4注意事项:


一:异常产生

在刚学习springMVC框架时,上传文件出现了以下HTTP Status 500 – Internal Server Error:

Exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. C:\Program Files\apache-tomcat-8.5.38\temp\upload_2f146db1_be01_4311_a3d8_e6c7cd69c8d3_00000002.tmp (拒绝访问。)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)javax.servlet.http.HttpServlet.service(HttpServlet.java:661)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)javax.servlet.http.HttpServlet.service(HttpServlet.java:742)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

Root Cause

org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. C:\Program Files\apache-tomcat-8.5.38\temp\upload_2f146db1_be01_4311_a3d8_e6c7cd69c8d3_00000002.tmp (拒绝访问。)org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)com.xy.controller.UserController.fileUpload(UserController.java:36)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflect.Method.invoke(Method.java:498)org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)javax.servlet.http.HttpServlet.service(HttpServlet.java:661)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)javax.servlet.http.HttpServlet.service(HttpServlet.java:742)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

Root Cause

java.io.FileNotFoundException: C:\Program Files\apache-tomcat-8.5.38\temp\upload_2f146db1_be01_4311_a3d8_e6c7cd69c8d3_00000002.tmp (拒绝访问。)java.io.FileOutputStream.open0(Native Method)java.io.FileOutputStream.open(FileOutputStream.java:270)java.io.FileOutputStream.<init>(FileOutputStream.java:213)java.io.FileOutputStream.<init>(FileOutputStream.java:162)org.apache.commons.io.output.DeferredFileOutputStream.thresholdReached(DeferredFileOutputStream.java:178)org.apache.commons.io.output.ThresholdingOutputStream.checkThreshold(ThresholdingOutputStream.java:224)org.apache.commons.io.output.ThresholdingOutputStream.write(ThresholdingOutputStream.java:128)org.apache.commons.fileupload.util.Streams.copy(Streams.java:107)org.apache.commons.fileupload.util.Streams.copy(Streams.java:70)org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:347)org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)com.xy.controller.UserController.fileUpload(UserController.java:36)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflect.Method.invoke(Method.java:498)org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)javax.servlet.http.HttpServlet.service(HttpServlet.java:661)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)javax.servlet.http.HttpServlet.service(HttpServlet.java:742)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

Note The full stack trace of the root cause is available in the server logs.

查询了一系列博客后,发现这是由于上传文件的大小超过了可以上传的临时文件限制。

二:fileUpload组件及Java Web中文件上传的原理方法

2.1基本原理

给出官网文档:upLoad。

组件FileUpload依赖于Commons IO组件,因此在继续之前,要确保在你的工程classpath中有描述页中提到的相应版本。(这里FileUpload版本为:commons- fileupload-1.2.1,Commons IO版本为:commons-io-1.4)。

最简单的示例(官网):

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);// Parse the request
List<FileItem> items = upload.parseRequest(request);

原理:

上传的文件要求包括一个根据RFC 1867(在HTML中基于表单的文件)编码的选项列表清单。组件FileUpload可以解析这个请求,并给你的应用程序提供一份独立上传的项目清单。无论每个项目背后如何执行都实现了FileItem接口。

这里将描述组件FileUpload库的普通API,这些API比较简单。不过,对于最终的实现,你可以参考最新的API流。

每一个文件项目都有一些属性,这些可能在你的应用程序中应用到。比如:每一个项目有一个名称name和内容类型content type,并提供了一个 InputStream访问其数据。另一方面,你处理项目的方法可能有所不同,这个依赖于是否这个项目是一个规则的表单域,即:这个数据是来自普通的表单文本,还是普通的HTML域或是一个上传文件。在FileItem接口中提供了处理这些问题的方法,可以更加方便的去访问这些数据。

组件FileUpload使用FileItemFactory工厂创建新的文件项目。这个给了组件FileUpload很大的灵活性。这个工厂拥有怎样创建项目的最终控制权。工厂执行过程中上传项目文件的临时数据可以存储在内存中或硬盘上。这个依赖于上传项目的大小(即:数据的字节)。不过这种行为可以在你的应用程序中适当的自定制。

解析:

在实现上传项目之前,当然需要解析这个请求。确保这个请求的确是一个正确的上传文件,组件FileUpload为了使这个判断简单,提供了一个静态的方法去做这个事情。

// 检测我们是否一个文件上传的请求

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

示例:

最简单的使用情况如下:

* 上传项目只要足够小,就应该将其保存在内存中。

* 较大的项目应该被写入到硬盘的临时文件中。

* 应该避免有非常大的上传项目。

* 设置项目默认的在内存中所占的空间,限制最大的上传请求,并设定临时文件 的位置。

处理这种情况下的请求非常的简单:

// 创建磁盘工厂

FileItemFactory factory = new DiskFileItemFactory();

// 创建处理工具

ServletFileUpload upload = new ServletFileUpload(factory);

// 解析

List <FileItem> items = upload.parseRequest(request);

这就是我们真正需要的全部代码。

处理的结果是生成了一个文件项目列表,每个文件项目实现一个FileItem接口。下面将介绍如何处理这些项目。

控制:

如果你的使用情况和上面描述的例子很接近,但是你需要在一点更多的控制限定文件的大小或临时文件的存放位置。你可以很容易的自定义上传实例或文件项目或两者的行为。下面例子展示了几种配置选项:

// 创建磁盘工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

// 设置参数

factory.setSizeThreshold(yourMaxMemorySize);

factory.setRepository(yourTempDirectory);

// 创建处理工具

ServletFileUpload upload = new ServletFileUpload(factory);

// 设置最大允许的尺寸

upload.setSizeMax(yourMaxRequestSize);

// 解析

List <FileItem> items = upload.parseRequest(request);

当然,每一个配置处理方法都是独立于其他方法的,但是如果你想一次性配置这个工厂,你可以使用工厂的另一个重载方法。像这样:

DiskFileItemFactory factory = new DiskFileItemFactory( yourMaxMemorySize, yourTempDirectory);

详细的接口文档:http://commons.apache.org/proper/commons-fileupload/javadocs/api-release/index.html

2.2实现代码

使用fileUpload固定步骤:

创建工厂类:DiskFileItemFactory factory=new DiskFileItemFactory();
    创建解析器:ServletFileUpload upload=new ServletFileUpload(factory);
    使用解析器解析request对象:List<FileItem> list=upload.parseRequest(request);

首先导入相关包。见上文。

1.jsp代码:

<%--Created by IntelliJ IDEA.User: 杨路恒Date: 2019/8/17 0017Time: 11:24
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传</title>
</head>
<body><form action="UserController/fileUpload1" method="post" enctype="multipart/form-data">选择文件:<input type="file" name="upload"><br>上传:<input type="submit" value="上传" name="uploadFile"></form>
</body>
</html>

2.配置springmvc-xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--扫描spring的包--><context:component-scan base-package="com.xy"></context:component-scan><!--视图解析器对象--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"></property><property name="suffix" value=".jsp"></property></bean><!--前端控制器,哪些静态资源不拦截--><mvc:resources location="/css/" mapping="/css/**"/>  <!-- 样式    --><mvc:resources location="/images/" mapping="/images/**"/>  <!-- 图片    --><mvc:resources location="/js/" mapping="/js/**"/>  <!-- javascript --><!--开启springMVC的支持,类型转换器生效--><mvc:annotation-driven></mvc:annotation-driven></beans>

3.配置web.xml:

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--前端控制器--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--中文乱码过滤器--><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

4.控制器代码:

package com.xy.controller;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 org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;@Controller
@RequestMapping("/UserController")
public class UserController {/*** 文件上传* @return*/@RequestMapping("/fileUpload1")public String fileUpload(HttpServletRequest request) throws Exception {System.out.println("文件上传");//使用fileupload组件上传文件//上传路径String path=request.getSession().getServletContext().getRealPath("/uploads");//判断该路径是否存在File file=new File(path);if (!file.exists()){file.mkdirs();}//解析request对象获取上传文件项DiskFileItemFactory diskFileItemFactory=new DiskFileItemFactory();
//        diskFileItemFactory.setSizeThreshold(1024*1024);    //设置内存缓冲区大小,系统默认值10KBFile temp=new File(request.getSession().getServletContext().getRealPath("/temp"));temp.mkdirs();System.out.println("建立成功");diskFileItemFactory.setRepository(temp);System.out.println(System.getProperty("java.io.tmpdir"));ServletFileUpload servletFileUpload=new ServletFileUpload(diskFileItemFactory);servletFileUpload.setFileSizeMax(100*1024*1024);//解析requestList<FileItem> items=servletFileUpload.parseRequest(request);for (FileItem item:items) {//判断当前item是否是上传文件对象if (item.isFormField()){//说明普通表单向}else {//说明上传文件项//获取文件名称String fileName=item.getName();//完成文件上传item.write(new File(path,fileName));System.out.println("写入成功");//删除临时文件,系统会自动删除
//                item.delete();}}return "success";}
}

5.success代码:

<%--Created by IntelliJ IDEA.User: 杨路恒Date: 2019/8/17 0017Time: 11:21
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><h1>文件上传成功</h1>
</body>
</html>

1.普通表单提交默认enctype="application/x-www-form-urlencoded";但是当表单中存在文件类型时,需要设置enctype="multipart/form-data",它不对字符进行编码,用于发送二进制的文件(即所有文件类型,如视频、图片、音乐、文档都可以用此类型entype);还有一种enctype="text/plain"用于发送纯文本内容。

2.表单请求方式必须为post。

3.接收时不能再用request.getParameter(),而是request.getInputStream()解析二进制流,得到ServletInputStream对象。

2.3重要方法

1.DiskFileItemFactory:

DiskFileItemFactory有两个方法 :setSizeThreshold和setRepository

setRepository方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以临时文件形式保存在磁盘上的存放目录。有一个对应的获得临时文件夹的 File getRespository() 方法。
        注意:当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:
System.getProperty("java.io.tmpdir");
Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。
 setSizeThreshold方法说明:
  
 Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。
       setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。

2.FileItem:

String getFieldName():获取表单项的name的属性值。
    String getName():获取文件字段的文件名。如果是普通字段,则返回null
    String getString():获取字段的内容。如果是普通字段,则是它的value值;如果是文件字段,则是文件内容。
    String getContentType():获取上传的文件类型,例如text/plain、image。如果是普通字段,则返回null。
    long getSize():获取字段内容的大小,单位是字节。
    boolean isFormField():判断是否是普通表单字段,若是,返回true,否则返回false。
    InputStream getInputStream():获得文件内容的输入流。如果是普通字段,则返回value值的输入流。

2.4注意事项:

1.文件名中文乱码处理:servletFileUpload.setHeaderEncoding("utf-8") 或 request.setCharacterEncoding("utf-8");
2.表单普通字段中文乱码处理:new String(str.getBytes("iso-8859-1","utf-8"));
3.设置内存缓冲区的大小,默认为10KB:diskFileItemFactory.setSizeThreshold(1024*1024);
4.指定临时文件目录,如果单个文件的大小超过内存缓冲区,该文件将会临时缓存在此目录下diskFileItemFactory.setRepository(file);
5.设置单个文件大小限制,如果有某个文件超过此大小,将抛出FileUploadBase.FileSizeLimitExceededException:servletFileUpload.setFileSizeMax(1024*1024*10);
6.设置所有文件,也就是请求大小限制,如果文件总和超过此大小,将抛出FileUploadBase.SizeLimitExceededException:servletFileUpload.setSizeMax(1024*1024*20);
7.利用UUID生成伪随机字符串作为文件名避免重复:UUID.randomUUID().toString();
8.将文件写到硬盘上。写完之后,系统会自动将放在临时文件目录的该文件删除:fileItem.write(new File(path,fileName));

fileUpload用来上传文件,主要任务解析request:

parseRequest(request)

SpingMVC框架:fileUpload组件原理和实现相关推荐

  1. ue4移动到一定距离_UE4移动组件详解(一)——移动框架与实现原理

    原文链接(转载请标明):UE4移动组件详解(一)--移动框架与实现原理_Jerish的博客-CSDN博客​blog.csdn.net 前言 关于UE4的移动组件,我写了一篇非常详细的分析文档.由于篇幅 ...

  2. python scrapy框架原理_Scrapy框架的工作原理是什么?

    Scrapy框架的工作原理是什么? Scrapy架构 学习Scrapy框架,从理解它的架构开始.图1所示是Scrapy的架构图. 从图1可知,Scrapy框架主要包含以下组件: (1)Scrapy E ...

  3. 好程序员web前端分享MVVM框架Vue实现原理

    好程序员web前端分享MVVM框架Vue实现原理,Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js和react.js更加简洁 ...

  4. dubbo 自定义路由_高性能可扩展分布式RPC框架Dubbo内核原理揭秘

    一.前言 整体来说,一个公司业务系统的演进流程基本都是从单体应用到多体应用.在单体应用时,不同业务模块相互调用直接在本地 JVM 进程内就可以完成;而变为多个应用时,相互之间进行通信的方式就不能简单的 ...

  5. 高性能可扩展分布式RPC框架Dubbo-内核原理揭秘

    一.前言 整体来说,一个公司业务系统的演进流程基本都是从单体应用到多体应用.在单体应用时,不同业务模块相互调用直接在本地 JVM 进程内就可以完成;而变为多个应用时,相互之间进行通信的方式就不能简单的 ...

  6. Spring框架的工作原理

    Spring框架是一个开源的Java平台,它为容易而快速的开发出耐用的Java应用程序提供了全面的基础设施.完成基础阶段的学习后,就会开始接触框架的知识,接下来就给大家简单讲解Spring框架的工作原 ...

  7. RPC框架:从原理到选型,一文带你搞懂RPC

    大家好,我是华仔,RPC系列的文章是我去年写的,当时写的比较散,现在重新进行整理.对于想学习RPC框架的同学,通过这篇文章,让你知其然并知其所以然,便于以后技术选型,下面是文章内容目录: RPC 什么 ...

  8. kpc v0.8.3发布,跨框架的组件库解决方案

    开发四年只会写业务代码,分布式高并发都不会还做程序员? >>>   kpc是金山云前端团队推出的跨框架的组件库解决方案,目前支持金山云内部框架Intact,以及流行的Vue/Reac ...

  9. 基于Vue的Quasar Framework 介绍 这个框架UI组件很全面

    基于Vue的Quasar Framework 介绍 这个框架UI组件很全面 基于Vue的Quasar Framework 中文网 http://www.quasarchs.com/ quasarfra ...

最新文章

  1. 在DataTable中创建计算列
  2. python3.5怎么使用-在ros中使用python3.5
  3. 学生上课睡觉班主任怎么处理_班主任案例:学生上课睡觉应对策略
  4. python数据结构_大O符号_学习笔记(1)
  5. Java IO 节点流与处理流类型
  6. asp.net core中使用cookie身份验证
  7. java saxexception_SAXException
  8. /dev/socket/vold exploit 本地提权漏洞
  9. C# ado.net数据库连接池,使用长连接访问数据库
  10. 朱福喜 java_与朱福喜的教科同步JAVA实验指导书
  11. 提交不了_志愿提交不了,不一定是系统问题。为了成功填报,建议试试这7步...
  12. Python常用中文字体对应名称
  13. Win10隐藏文件资源管理器中的我的电脑上方的7个文件夹
  14. 从白嫖百度AI Studi Telsa V100 32G训练资源到使用tensorflow训练全流程(个人用)
  15. 服务器站群16c多少个ip?不同C段IP怎么计算
  16. kswapd和pdflush
  17. 2018年什么编程语言最值得学习
  18. 如何控制input的输入方向
  19. 如何利用阿里云市场购买并使用短信服务
  20. zsh与oh-my-zsh ← 阳志平的个人网站::技术 zsh与oh-my-zsh ← 阳志平的个人网站::技术...

热门文章

  1. 利用C语言中的setjmp和longjmp,来实现异常捕获和协程
  2. 如何把一个float存到一个长度为4的char数组中?
  3. Datawhale-零基础入门NLP-新闻文本分类Task06
  4. python文本编辑器报错_notepad++编辑器中运行python程序时需要注意的编码格式
  5. linux终端贪吃蛇,分享|nSnake: 在Linux的终端上玩经典的贪食蛇游戏
  6. python写xml文件_用python写xml文件
  7. 摩尔斯电码转换python编码_Morse Code 用Python做个摩斯密码转换器
  8. es6 数组合并_JavaScript学习笔记(十九)-- ES6
  9. Vue项目部署,打包发布上线
  10. 四、数据预处理——处理连续型特征:二值化与分段