Java 文件上传组件 Apache Commons FileUpload 应用指南(二)——FileUpload如何工作?

 在最初的 http 协议中,没有上传文件方面的功能。RFC1867("Form-based File Upload in HTML".)
 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用
户指定的文件发送到服务器。服务器端的网页程序,如
 php, asp, jsp 等,可以按照此规范,解析出用户
发送来的文件。

2.1客户端

简单来说,RFC1867规范要求http协议增加了file类型的input标签,用于浏览需要上传的文件。同时
要求
FORM表单的enctype属性设置为“multipart/form-data”,method属性设置为“post”即可,下面是我们文
件上传页面的表单代码:

<form action="<%=request.getContextPath()%>/servlet/SimpleUpload" enctype="multipart/form-data" 
method
="post">

文本1<input type="text" name="text1" value="文本1"><br>

文件2<input type="text" name="text2" value="文本2"><br>

文件1<input type="file" name="file1"><br>

文件2<input type="file" name="file2"><br>

文件2<input type="file" name="file3"><br>

<input type="submit" value="开始上传">

</form>

2.2 服务器端

一个文件上传请求的消息实体由一系列根据 RFC1867"Form-based File Upload in HTML".)编码的项目
(文本参数和文件参数)组成。自己编程来解析获取这些数据是非常麻烦的,还需要了解
RFC1867规范对请
求数据编码的相关知识。
FileUpload 可以帮助我们解析这样的请求,将每一个项目封装成一个实现了FileItem
接口的对象,并以列表的形式返回。所以,我们只需要了解FileUploadAPI如何使用即可,不用管它们的底
层实现。让我们来看一个简单文件上传处理代码:

DiskFileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload uploader = new ServletFileUpload(factory);

List<FileItem> list = uploader.parseRequest(request);

if (item.isFormField()){

// 处理普通表单域

String field = item.getFieldName();//表单域名

String value = item.getString("GBK");

else {

//将临时文件保存到指定目录

String fileName = item.getName();//文件名称

String filepath = "您希望保存的目录/" + fileName;

item.write(new File(filepath));//执行保存

}

    怎么样?简单吧!下面我们来继续了解一些必须了解的API

FileItem接口

org.apache.commons.fileupload.disk.DiskFileItem实现了FileItem接口,用来封装单个表单字段元素的
数据。通过调用
FileItem 定义的方法可以获得相关表单字段元素的数据。我们不需要关心DiskFileItem的具
体实现,在程序中可以采用
FileItem接口类型来对DiskFileItem对象进行引用和访问。FileItem类还实现了
Serializable接口,以支持序列化操作。

下图是一个文件上传表单:



上图表单提交的http数据包的内容:

POST /demo/servlet/SimpleUpload HTTP/1.1

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, 
application/vnd.ms-excel, application/vnd.ms-powerpoint, */*

Referer: http://127.0.0.1:8080/demo/simpleUpload.jsp

Accept-Language: zh-cn

Content-Type: multipart/form-data; boundary=---------------------------7da1772c5504c6

UA-CPU: x86

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

Host: 127.0.0.1:8080

Content-Length: 184423

Connection: Keep-Alive

Cache-Control: no-cache

Cookie: JSESSIONID=BD8E58E5BAD9B559C0262077FB5E0B4E

-----------------------------7da1772c5504c6

Content-Disposition: form-data; name="text1"

郑州蜂鸟科技有限公司

-----------------------------7da1772c5504c6

Content-Disposition: form-data; name="text2"

申林

-----------------------------7da1772c5504c6

Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\All Users\
Documents\My Pictures\示例图片\Blue hills.jpg"

Content-Type: image/pjpeg

大量二进制数据内容,无法复制 …….

-----------------------------7da1772c5504c6

Content-Disposition: form-data; name="file2"; filename="C:\Documents and Settings\All Users\
Documents\My Pictures\示例图片\
Sunset.jpg"

Content-Type: image/pjpeg

大量二进制数据内容,无法复制 …….

-----------------------------7da1772c5504c6

Content-Disposition: form-data; name="file3"; filename="C:\Documents and Settings\All Users\
Documents\My Pictures\示例图片\
Water lilies.jpg"

Content-Type: image/pjpeg

大量二进制数据内容,无法复制 …….

从第一行,也就是请求行,我们可以看出这是一个post请求。在请求头部部分,我们可以看到这样
一个头部信息:

Content-Type: multipart/form-data; boundary=---------------------------7da1772c5504c6

其中红色部分说明该请求是一个multipart/form-data类型即多媒体类型的请求。蓝色部分boundary的值
定义了一个字段分隔界线。在消息体部分可以看出每个表单字段元素数据之间采用字段分隔界线进行分
割,两个分隔界线间的内容称为一个分区,每个分区中的内容包括两部分,一部分是对表单字段元素进
行描述的描述头,另外一部分是表单字段元素的主体内容。 

通过对比描述头,我们可以很容易区分文本字段和文件字段。不管是文件字段还是文本字段,都有
name属性,即该字段作为一个表单域的名字。而文件字段还有filename,即上传文件本身的名字。另外,
还有
conten-type属性用于指明文件的类型。

每一个表单字段,不管它是文本还是文件,都被封装成 FileItem 对象,我们称之为文件项,当文件
项数据内容尺寸小于
DiskFileItemFactory 的sizeThreshold 属性设置的临界值时,直接保存在内存中;否则,
将数据流以临时文件的形式,保存在 
DiskFileItemFactory 的 repository 属性指定的临时目录中。临时文件
名形如“
upload_00000005(八位或八位以上的数字).tmp”。
FileItem类内部提供了维护临时文件名中的
数值不重复的机制,以保证了临时文件名的唯一性。另外,如何保证临时文件能被及时清除,释放宝贵
的系统资源,是非常重要的,我们将在后面讲解。 

FileItem类常用的方法:

1.  boolean isFormField()方法

isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字
段,如果是普通表单字段则返回true,否则返回false

2.  String getName()方法 

getName方法用于获得文件上传字段中的文件名,即表单字段元素描述头中的filename属性值,如“C:\Documents and Settings\All Users\Documents\My Pictures\示例图片\Sunset.jpg”。如果FileItem类对象对
应的是普通表单字段,
getName方法将返回null即使用户没有通过网页表单中的文件字段传递任何
文件,但只要设置了文件表单字段的name属性,浏览器也会将文件字段的信息传递给服务器,
只是文件名和文件内容部分都为空,但这个表单字段仍然对应一个
FileItem对象,此时,
getName
方法返回结果为空字符串
"",读者在调用Apache文件上传组件时要注意考虑这个情况。

注意:上面的数据包是通过IE提交,所以是完整的路径和名称。如 
C:\Documents and Settings\All Users\Documents\My Pictures\示例图片\
Sunset.jpg。如果是其它浏览
器,如火狐和Chromium,则仅仅是名字,没有路径,如
Sunset.jpg

3.  String getFieldName()方法

getFieldName方法用于返回表单字段元素描述头的name属性值,也是表单标签name属性的值。例
如“
name=file1”中的“file1”。

4.  void write(File file)方法

write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主
体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通
表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。

5.  String getString()方法

getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:

public java.lang.String getString()

public java.lang.String getString(java.lang.String encoding)

throws java.io.UnsupportedEncodingException

前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容
转换成字符串。
如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个
getString方法,并为之传递正确的字符集编码名称。

6.  String getContentType()方法

getContentType 方法用于获得上传文件的类型,即表单字段元素描述头属性“Content-Type”的值,
如“
image/jpeg”。如果FileItem类对象对应的是普通表单字段,该方法将返回null

7.  boolean isInMemory()方法

isInMemory方法用来判断FileItem对象封装的数据内容是存储在内存中,还是存储在临时文件中,
如果存储在内存中则返回true,否则返回false

8.  void delete()方法

delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,
delete方法将删除该临时文件。

尽管当FileItem对象被垃圾收集器收集时会自动清除临时文件,但及时调用delete方法可以更早的
清除临时文件,释放系统存储资源。另外,当系统出现异常时,仍有可能造成有的临时文件被永久
保存在了硬盘中。

9.  InputStream getInputStream()方法

    以流的形式返回上传文件的数据内容。

10. long getSize()方法

返回该上传文件的大小(以字节为单位)。

DiskFileItemFactory

将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现对象的任务
由 
org.apache.commons.fileupload.FileItemFactory 接口的默认实现 
org.apache.commons.fileupload.disk.DiskFileItemFactory 来完成。当上传的文件项目比较小时,直接保
存在内存中
(速度比较快)比较大时,以临时文件的形式,保存在磁盘临时文件夹(虽然速度
慢些,但是内存资源是有限的)。

属性

1) public static final int DEFAULT_SIZE_THRESHOLD :将文件保存在内存还是
磁盘临时文件夹的默认临界值,值为10240,即10kb

2) private File repository:用于配置在创建文件项目时,当文件项目大于临界值时使
用的临时文件夹,默认采用系统
默认的临时文件路径,可以通过系统属性 java.io.tmpdir 
获取。如下代码:

System.getProperty("java.io.tmpdir");

3) private int sizeThreshold用于保存将文件保存在内存还是磁盘临时文件夹的临界值

构造方法

1) public DiskFileItemFactory():采用默认临界值和系统临时文件夹构造文件项工厂对象。

2) public DiskFileItemFactory(int sizeThreshold,File repository):采用参数指定临界值和系统临时
文件夹构造文件项工厂对象。

FileItem createItem() 方法

根据DiskFileItemFactory相关配置将每一个请求消息实体项目创建 成DiskFileItem 实例,并返回。
该方法从来不需要我们亲自调用,FileUpload组件在解析请求时内部使用。

void setSizeThreshold(int sizeThreshold)

Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便
在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为
Java虚拟机默认可以使
用的内存空间是有限的,超出限制时将会抛出“
java.lang.OutOfMemoryError”错误。如果上传的文件
很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时
文件来保存这些数据;但如果上传的文件很小,例如
600个字节的文件,显然将其直接保存在内存中
性能会更加好些。

setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节
为单位的
int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的
getSizeThreshold() 方法用来获取此临界值。

void setRepository(File repository)

setRepositoryPath方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以
临时文件形式保存在磁盘上的存放目录。有一个对应的获得临时文件夹的 File getRespository() 方法。

注意:当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以
通过系统属性 
java.io.tmpdir 获取。如下代码:

System.getProperty("java.io.tmpdir");

Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。

ServletFileUpload 类

org.apache.commons.fileupload.servlet.ServletFileUpload类是Apache文件上传组件处理文件上传的
核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。

使用其 parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装
成一个
FileItem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。

如果你希望进一步提高新能,你可以采用 getItemIterator 方法,直接获得每一个文件项的数据输
入流,对数据做直接处理。

在使用ServletFileUpload对象解析请求时需要根据DiskFileItemFactory对象的属性 sizeThreshold(临
界值)和
repository(临时目录) 来决定将解析得到的数据保存在内存还是临时文件中,如果是临时
文件,保存在哪个临时目录中?。所以,我们需要在进行解析工作前构造好
DiskFileItemFactory对象,
通过ServletFileUpload对象的构造方法或
setFileItemFactory()方法设置 ServletFileUpload对象的
fileItemFactory属性。

ServletFileUpload继承结构:

java.lang.Object

|org.apache.commons.fileupload.FileUploadBase

     |org.apache.commons.fileupload.FileUpload

|org.apache.commons.fileupload.servlet.ServletFileUpload

构造方法:

1) public ServletFileUpload():构造一个未初始化的实例,需要在解析请求之前先调用
setFileItemFactory()方法设置 fileItemFactory属性。

2) public ServletFileUpload(FileItemFactory fileItemFactory):构造一个实例,并根据参数
指定的
FileItemFactory 对象,设置 fileItemFactory属性。

ServletFileUpload类常用方法:

1. public void setSizeMax(long sizeMax)方法

setSizeMax方法继承自FileUploadBase类,用于设置请求消息实体内容(即所有上传数据)的最大
尺寸限制,
以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数以字节为单位的
long型数字

在请求解析的过程中,如果请求消息体内容的大小超过了setSizeMax方法的设置值,将会抛出
FileUploadBase内部定义的SizeLimitExceededException异常(FileUploadException的子类)。如:

org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException
the request was rejected because its size (1649104) exceeds the configured 
maximum (153600)

该方法有一个对应的读方法:public long getSizeMax()方法。

2. public void setFileSizeMax(long fileSizeMax)方法

setFileSizeMax方法继承自FileUploadBase类,用于设置单个上传文件的最大尺寸限制,以防止客户
端恶意上传超大文件来浪费服务器端的存储空间。其
参数以字节为单位的long型数字。该方法有一个
对应的读方法:public long geFileSizeMax()方法。

在请求解析的过程中,如果单个上传文件的大小超过了setFileSizeMax方法的设置值,将会抛出
FileUploadBase内部定义的FileSizeLimitExceededException异常(FileUploadException的子类)。如:

org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file1 exceeds its
 maximum permitted size of 51200 characters.

3. public List parseRequest(javax.servlet.http.HttpServletRequest req)

parseRequest 方法是ServletFileUpload类的重要方法,它是对HTTP请求消息体内容进行解析的入口
方法。
解析出FORM表单中的每个字段的数据,并将它们分别包装成独立的FileItem对象,然后将这
FileItem对象加入进一个List类型的集合对象中返回。

该方法抛出FileUploadException异常来处理诸如文件尺寸过大、请求消息中的实体内容的类型不
是“
multipart/form-data”、IO异常、请求消息体长度信息丢失等各种异常。每一种异常都是
FileUploadException的一个子类型。

4. public FileItemIterator getItemIterator(HttpServletRequest request)

getItemIterator方法和parseRequest 方法基本相同。但是getItemIterator方法返回的是一个迭代
器,该迭代器中保存的不是
FileItem对象,而是FileItemStream 对象,如果你希望进一步提高新能,
你可以采用 
getItemIterator 方法,直接获得每一个文件项的数据输入流,做底层处理;如果性能不
是问题,你希望代码简单,则采用
parseRequest方法即可。
 

5. public stiatc boolean isMultipartContent(HttpServletRequest req)

isMultipartContent方法方法用于判断请求消息中的内容是否是“multipart/form-data”类型,是则返
true,否则返回false
isMultipartContent方法是一个静态方法,不用创建ServletFileUpload类的实例对
象即可被调用。

6. getFileItemFactory()setFileItemFactory(FileItemFactory)方法

方法继承自FileUpload类,用于设置和读取fileItemFactory属性。

7. public void setProgressListener(ProgressListener pListener)

设置文件上传进度监听器。关于监听器的具体内容,将在后面学习。该方法有一个对应的读取
方法:ProgressListener getProgressListener()

8.public void setHeaderEncoding()方法

在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路
径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取
这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。

setHeaderEncoding方法继承自FileUploadBase类,用于设置上面提到的字符编码。如果没有设置,
则对应的读方法g
etHeaderEncoding()方法返回null,将采用HttpServletRequest设置的字符编码,如果
HttpServletRequest的字符编码也为null,则采用系统默认字符编码。可以通过一下语句获得系统默认
字符编码:

System.getProperty("file.encoding"));

好,到这里我们学习了主要的一些API,足够我们来完成一个简单文件上传的功能了,下一章,
我们将一起来编写一个文件上传应用程序。

 

郑州蜂鸟科技有限公司 申林 QQ:38185398  郑州软件开发兴趣小组群:38236716

学软件开发,到蜂鸟科技!超强的师资力量 、完善的课程体系 、超低的培训价格 、真实的企业项目。

地址:郑州市文化路丰产路口东50米丰产路21号SOHO世纪城西塔20楼F 
电话:0371-63839606  手机:13838505572(申老师) 13673990036 (许老师)
QQ: 1073422643  1群:47614738 2群:108157678  
网址:www.ntcsoft.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytest单侧模块_入门汇总

Pytest简单介绍 &#xff08;pytest是python的一个测试框架&#xff0c;主要是用来进行一些小的测试&#xff09; 安装&#xff1a;pip install -U pytest查看是否安装成功&#xff1a;pytest --version运行&#xff1a;在当前文件所在目录下执行pytest&#xff0c;会寻找当前目…

pythonreshape函数三个参数_详解numpy.ndarray.reshape()函数的参数问题

我们知道numpy.ndarray.reshape()是用来改变numpy数组的形状的&#xff0c;但是它的参数会有一些特殊的用法&#xff0c;这里我们进一步说明一下。代码如下&#xff1a;import numpy as npclass Debug:def __init__(self):self.array1 np.ones(6)def mainProgram(self):print(…

javafx 和swing_集成JavaFX和Swing

javafx 和swing我刚刚完成了对使用Swing的应用程序组件的重写&#xff0c;现在正在使用JavaFX&#xff0c;最后得到了与更大的swing应用程序集成的JavaFX组件。 这是一个很大的应用程序&#xff0c;重写花了我一段时间&#xff0c;最后一切都很好&#xff0c;我很高兴自己做到了…

servlet.jar--jar not loaded错误

出错信息&#xff1a;validateJarFile(D:\Program Files\apache-tomcat-6.0.29\webapps\BookShop\WEB-INF\lib\servlet.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class 造成这种错误的原因有两个&#xff1a;serv…

练习6.6

6.6&#xff1a;说明形参、局部变量以及局部静态变量的区别。编写一个函数&#xff0c;同时用到这三种形式。 Ans&#xff1a;形参及函数体内定义的变量&#xff0c;都是局部变量&#xff0c;必须进行初始化&#xff0c;否则会出现未定义行为&#xff0c;这是由于局部变量的生命…

java map 最大值_MAP集合选出最大值

import java.util.Arrays;import java.util.HashMap;import java.util.Map;import org.junit.Test;public class TestHashMap {//统计各空气质量的最高值Testpublic void test1(){String pm25 "农展馆423,东四378,丰台花园406,天坛322,海淀区万柳398," "官园40…

Apache Hadoop HDFS数据节点Apache Mesos框架

介绍 该项目允许在Mesos上运行HDFS。 您应该熟悉HDFS和Mesos基础知识&#xff1a; http://mesos.apache.org/documentation/latest/ https://hadoop.apache.org/docs/r2.7.2/hdfs_design.html 项目要求&#xff1a; Mesos 0.23.0 JDK 1.7.x Hadoop 1.2.x或2.7.x 流浪汉 …

java byte 转 c_C 和 Java 之间的byte数据的转换问题

C语言里通常可能开发人员直接定义struct 作为数据包,因此在java客户端接收struct 中的数据时候,受整数等类型的高低位存放的影响,需要进行相应的转换,参考:转换代码如下:package com.lizongbo.util;/**** Title: 数字转换工具类** Description: 将数字类型与byte数组互相转换**…

MyEclipse中如何设置 jdk 和 jre 编译运行环境

MyEclipse设置JDK和JRE具体的应用版本其实很简单&#xff0c;分为三种状况&#xff1a; 1、设置默认使用的JDK和JRE环境。 具体步骤&#xff1a;菜单window-preferences-java-Installed JRES。 点中了&#xff0c;右边的窗口点ADD按钮&#xff0c;记住选择添加安装了Java目录下…

dubbo集群服务下一台服务挂了对服务调用的影响

一、问题描述&#xff1a;项目中2台dubbo服务给移动端提供查询接口&#xff0c;移动端反应说查询时而很快(秒刷)&#xff0c;时而很慢(4-5秒)。 二、问题分析&#xff1a; 1、问题猜想&#xff1a;网络不稳定原因导致&#xff0c;但是切换公司wifi和手机4G,问题依旧存在。说明问…

C89与C99标准比较

1、增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符&#xff0c;它是初始访问指针所指对象的惟一途径&#xff0c;因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元&#xff0c;或者指向由malloc()函数所分配的内存变量。restri…

java rest客户端_Java中的简单REST客户端

java rest客户端如今&#xff0c;大多数用于与某些服务器通信的移动应用程序都使用REST服务。 这些服务也是JavaScript或jQuery的常用惯例。 现在&#xff0c;我知道在Java中为REST服务创建客户端的2种方法&#xff0c;在本文中&#xff0c;我将尝试演示这两种方法&#xff0c;…

C++并发编程实战---阅读笔记

1. 当把函数对象传入到线程构造函数中时&#xff0c;需要避免“最令人头痛的语法解析”。如果传递了一个临时变量&#xff0c;而不是一个命名的变量&#xff1b;C编译器会将其解析为函数声明&#xff0c;而不是类型对象的定义。 例如&#xff1a; class background_task { publ…

java md2_java中加密的实现方法(MD5,MD2,SHA)

java中加密的实现方法(MD5&#xff0c;MD2&#xff0c;SHA)实例代码&#xff1a;注释都很清楚&#xff0c;import java.security.MessageDigest;import javax.xml.bind.annotation.adapters.HexBinaryAdapter;public class Main {static String src "Hello,sahadev!"…

Java向后不兼容历史的观察

在大多数情况下&#xff0c;Java是一个非常向后兼容的编程语言。 这样做的好处是&#xff0c;与大规模破坏兼容性相比&#xff0c;大型系统通常可以相对容易的方式升级为使用Java的较新版本。 这样做的主要缺点是Java坚持了一些设计决策&#xff0c;这些决策自那时以来就被认为…

C语言中输入输出格式控制

1、C语言中&#xff0c;非零值为真&#xff0c;真用1表示&#xff1b;零值为假&#xff0c;假用0表示。 2、转义字符参考&#xff1a; \a 蜂鸣&#xff0c;响铃 \b 回退&#xff1a;向后退一格 \f 换页 \n 换行 \r 回车&#xff0c;光标到本行行首 \t 水平制表 …

java udp 接受阻塞_Java UDP发送与接收

IP地址&#xff1f;端口号&#xff1f;主机名&#xff1f;什么是Socket?什么是UDP&#xff1f;什么是TCP&#xff1f;UDP和TCP区别&#xff1f;以上问题请自行百度&#xff0c;有标准解释&#xff0c;此处不再赘述&#xff0c;直接上干货&#xff01;实例&#xff1a;发送端&a…

JavaScript 运行机制详解:Event Loop

参考地址&#xff1a;http://www.ruanyifeng.com/blog/2014/10/event-loop.html 一、为什么JavaScript是单线程&#xff1f; JavaScript语言的一大特点就是单线程&#xff0c;也就是说&#xff0c;同一个时间只能做一件事。那么&#xff0c;为什么JavaScript不能有多个线程呢&a…

原码, 反码, 补码 详解

本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希望本文对大家学习计算机基础有所帮助! 一. 机器数和真值 在学习原码, 反码…

java eden space_JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)...

1.内存区域划分根据我们之前介绍的垃圾收集算法&#xff0c;限定商用虚拟机基本都采用分代收集算法进行垃圾回收。根据对象的生命周期的不同将内存划分为几块&#xff0c;然后根据各块的特点采用最适当的收集算法。大批对象死去、少量对象存活的&#xff0c;使用复制算法&#…