I/O流
一直用到的不多,是时候该搞清楚了。
-
Java中I/O流的分类
- 按照流的流向分:输入流和输出流
- 按照操作单元分:字节流和字符流
- 按照流的角色分:节点流和处理流
I/O分类 字节流 字符流 输入流 InputStream Reader 输出流 OutputStream Writer -
Java的I/O类的类库
IO类非常之多,也正是为了让他们分工明确,各自负责不同的功能实现。用途有:
- 文件访问
- 网络访问
- 内存缓存访问
- 线程内部通信(管道)
- 缓冲
- 过滤
- 解析
- 读写文本(Reader、Writer)
- 读写基本数据(int、long。。。)
- 读写对象
上图表示的是各个类之间的关系
上图表示的是各个类所负责的媒介
-
I/O流的基本用法
3.1. 字节流(InputStram和OutputStream)
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class AboutIO { public static void writeByte2File() throws IOException { // TODO 自动生成的方法存根 String hello = "hello world"; byte[] bytes = hello.getBytes(); File file = new File("G:/Java/hello.text"); OutputStream stream = new FileOutputStream(file); stream.write(bytes); stream.flush(); stream.close(); } public static void readFile2Bytes() throws IOException { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello.text"); //创建文件长度大小的byte数组 byte[] bytes = new byte[(int)(file.length())]; InputStream stream = new FileInputStream(file); int size = stream.read(bytes); System.out.println("大小:"+size+"内容"+new String(bytes)); stream.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); readFile2Bytes(); } } 复制代码
大小:11内容hello world 复制代码
3.2. 字符流(Reader和Writer)
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class AboutIO { public static void writeChar2File() throws IOException { // TODO 自动生成的方法存根 String hello = "Hello,Hello"; File file = new File("G:/Java/hello1.text"); FileWriter writer = new FileWriter(file); writer.write(hello); writer.close(); } public static void readFile2Char() throws IOException { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello1.text"); FileReader reader = new FileReader(file); char[] chars = new char[(int)file.length()]; int size = reader.read(chars); System.out.println("大小:"+size+",内容:"+new String(chars)); reader.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); writeChar2File(); readFile2Char(); } } 复制代码
大小:11,内容:Hello,Hello 复制代码
3.3. 字节流转换为字符流
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; public class AboutIO { public static void byte2Char() throws IOException { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello1.text"); InputStream inputStream = new FileInputStream(file); Reader reader = new InputStreamReader(inputStream); char[] chars = new char[(int)file.length()]; int size = reader.read(chars); System.out.println("大小:"+size+",内容:"+new String(chars)); inputStream.close(); reader.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); byte2Char(); } } 复制代码
大小:11,内容:Hello,Hello 复制代码
3.4. IO类的组合
即将一个流放入另一个流的构造器中,组合可以得到更多功能的实现 复制代码
3.5. 文件媒介File的读写
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; public class AboutIO { public static void fileOption() { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello/2.text"); boolean exists = file.exists(); System.out.println("G:/Java/hello/2.text是否存在?"+exists); File file1 = new File("G:/Test111/test/1.text"); boolean mkdir = file1.mkdir(); System.out.println("mkdir:"+mkdir); boolean file12 = file1.exists(); System.out.println("G:/Test111/test/1.text存在吗"+file12); File file2 = new File("G:/Test222/test2.text"); boolean mkdirs = file2.mkdirs(); System.out.println("mkdirs:"+mkdirs); System.out.println("mkdirs会创建多级不存在目录,mkdir只会创建一个目录,且父目录必须存在"); File hello = new File("G:/Java/hello/1.text"); //内容Hello,Hello hello.renameTo(new File("G:/Java/helloHello.text")); boolean delete = hello.delete(); System.out.println("helloHello还存在吗?"+hello.exists()); boolean file11 = file1.isDirectory(); System.out.println("G:/Test111/test/1.text是目录吗?"+file11); File file3 = new File("G:/Test222"); File file4 = new File("G:/Test222/test2.text"); File[] listFiles = file3.listFiles(); String[] list = file3.list(); for(File f : listFiles) { System.out.println("G:/Test222下的listFiles方法---遍历出文件的文件名:"+f.getName()); } for(String s:list) { System.out.println("G:/Test222下的list方法---遍历出文件的文件名:"+s); } } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); fileOption(); } } 复制代码
G:/Java/hello/2.text是否存在?false mkdir:false G:/Test111/test/1.text存在吗true mkdirs:false mkdirs会创建多级不存在目录,mkdir只会创建一个目录,且父目录必须存在 helloHello还存在吗?false G:/Test111/test/1.text是目录吗?true G:/Test222下的listFiles方法---遍历出文件的文件名:test2.text G:/Test222下的list方法---遍历出文件的文件名:test2.text 复制代码
3.6. 文件的随机位置读写
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.Reader; public class AboutIO { public static void randomReadFile() throws IOException { // TODO 自动生成的方法存根 //r--只读;rw--读写;rws--读写打开,并对内容或元数据同步写入底层存储设备; //rwd--读写打开,对文件的更新同步至底层存储设备 File fileO = new File("G:/Java/hello3.text"); FileOutputStream stream = new FileOutputStream(fileO); String content = "如果你和许多人一样,你可能已经决定要少花点时间盯着手机看了。\r\n" + "这是个好主意:越来越多的证据表明,我们在我们的智能手机上耗费的时间正在干扰我们的睡眠、自尊、人际关系、记忆、注意力持续时间、创造力、生产力以及解决问题和决策的能力。\r\n" + "但令我们重新思考与这些设备的关系的,还有另一个原因。通过长期提高身体主要的应激激素——皮质醇的水平,我们的手机可能会威胁我们的健康,并缩短我们的寿命。\r\n" + "到目前为止,大多数关于手机生化效应的讨论都集中在多巴胺上,这是一种帮助我们形成习惯和上瘾的大脑化学物质。就像老虎机一样,智能手机和应用程序明显是为了触发多巴胺的释放而设计的,目的就是让我们难以放下手中的设备。\r\n" + "这种对我们多巴胺系统的操纵,正是许多专家认为我们正在对我们的手机产生行为上瘾的原因。但我们的手机对皮质醇的影响可能更令人担忧。\r\n" + "皮质醇是影响战逃决策的主要激素。它的释放会引发一些生理变化,比如血压、心率和血糖的飙升,这些变化会帮助我们对紧急的人身威胁做出反应并存活下来。\r\n" + "如果你的身体确实存在危险,比如一头公牛正在向你冲来,这些反应将可以挽救你的生命。但我们的身体也会释放皮质醇以应对情绪压力,在这种情况下,心率加快并没有多大好处,比如查看手机时发现老板发来的一封愤怒的邮件。\r\n"; byte[] b = content.getBytes(); stream.write(b); stream.close(); RandomAccessFile file = new RandomAccessFile("G:/Java/hello3.text", "rw"); file.seek(file.length()/3); String s = "--插入--"; // s = new String(s.getBytes("ISO-8859-1"),"utf-8"); byte[] bytes = s.getBytes(); file.write(bytes); file.seek(10); long pointer = file.getFilePointer(); byte[] contents = new byte[1024]; file.read(contents); long pointEnd = file.getFilePointer(); System.out.println("pointerStart:"+pointer); System.out.println("pointerEnd:"+pointEnd); System.out.println("content:"+new String(contents)); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); //fileOption(); randomReadFile(); } } 复制代码
pointerStart:10 pointerEnd:1034 content:��许多人一样,你可能已经决定要少花点时间盯着手机看了。 这是个好主意:越来越多的证据表明,我们在我们的智能手机上耗费的时间正在干扰我们的睡眠、自尊、人际关系、记忆、注意力持续时间、创造力、生产力以及解决问题和决策的能力。 但令我们重新思考与这些设备的关系的,还有另一个原因。通过长期提高身体主要的应激激素——皮质醇的水平,我们的手机可能会威胁我们的�--插入--缩短我们的寿命。 到目前为止,大多数关于手机生化效应的讨论都集中在多巴胺上,这是一种帮助我们形成习惯和上瘾的大脑化学物质。就像老虎机一样,智能手机和应用程序明显是为了触发多巴胺的释放而设计的,目的就是让我们难以放下手中的设备。 这种对我们多巴胺系统的操纵,正是许多专家认为我们正在对我们的手机产生行为上瘾的原因。但我们的手机对皮质 复制代码
其中: file.seek(file.length()/3); String s = "--插入--"; // s = new String(s.getBytes("ISO-8859-1"),"utf-8"); byte[] bytes = s.getBytes(); file.write(bytes); 这段如果不写,也就是不用randomAccessFile的write来写入,获得的txt文件打开时,没有乱码,但是如果使用了write,控制台输出没有问题,但是,txt文件中就会变成乱码,即便使用注释部分的代码也没能解决。 复制代码
不使用randomAccessFile的write
使用randomAccessFile的write3.7. 管道媒介
在java中,管道的作用是实现同一虚拟机中两个不同线程间的交流。和管道相关的类是:PipedInputStream和PipedOutputStream。
package cn.wh3t; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.RandomAccessFile; import java.io.Reader; public class AboutIO { public static void pipedStream() throws IOException { // TODO 自动生成的方法存根 final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream); Thread thread1 = new Thread(new Runnable() { @Override public void run() { // TODO 自动生成的方法存根 try { pipedOutputStream.write("piped".getBytes()); } catch (IOException e) { // TODO: handle exception } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { // TODO 自动生成的方法存根 try { int data = pipedInputStream.read(); while (data!=-1) { System.out.println((char)data); data = pipedInputStream.read(); } } catch (IOException e) { // TODO: handle exception }finally { try { pipedInputStream.close(); } catch (IOException e2) { // TODO: handle exception } } } }); thread1.start(); thread2.start(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); //fileOption(); //randomReadFile(); pipedStream(); } } 复制代码
p i p e d 复制代码
就像是两条管道,一条负责输入,一条负责输出。
3.8. 网络媒介
JavaIO面向网络即Java网络编程,核心是socket,同磁盘操作一样,Java网络编程对应两套api:IO和NIO。
JavaAPI中提供了两套NIO,一套标准输入输出NIO,一套网络编程NIO。
NIO与IO的最大区别:IO以流的形式处理数据(简单便捷,但处理得慢),NIO以块的形式处理数据(速度比流快,但不如流简单)。
-
关于Buffer
Buffer和Channel是标准NIO中的核心对象,几乎每个IO操作都用得到。任何来源和目标数据都必须通过一个Channel对象,Buffer即容器对象,所有Channel对象无论读写都要通过Buffer。
Buffer实质上是一个数组,通常是字节数组,但也可以是其他了类型的数组。但一个缓冲区不仅仅是一个数组,重要的是,它提供了对数据的结构化访问,而且还可以跟踪系统的读写进程。
使用Buffer读写数据一般遵循以下四个步骤:
- 写入数据到Buffer
- 调用flip()方法 (将Buffer从写模式切换到读模式)
- 从Buffer中读取数据
- 调用clear()或者compact()方法 (clear清空整个缓冲区,compact清除已读数据。任何未读数据都被移到缓冲区起始处,新写入的数据放到未读数据后面)
Java NIO中具体的Buffer类型如下:(Buffer中的数据可以是这些基本类型,Mapped有些特殊--深入浅出MappedByteBuffer)
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
-
关于Channel
Channel和流的不同
- Channel是双向的,兼具读写,而流是单向的
- Channel支持异步的读写
- 对Channel的读写必须通过Buffer对象
Java NIO中Channel的类型如下:
- FileChannel (用于文件数据的读写)
- DataGramChannel (用于UDP数据的读写)
- SocketChannel (用于TCP数据的读写)
- ServerSocketChannel (允许我们监听TCP链接请求,每个请求都会创建一个SocketChannel)
-
NIO的读写操作
从文件读取数据的话,需要3步,写入也一样
- 从FileInputStream中获取Channel
- 创建Buffer
- 从Channel读取数据到Buffer
package cn.wh3t; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.RandomAccessFile; import java.io.Reader; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class AboutIO { public static void NIOReadAndWriteByCopyFile(String src,String dst) throws IOException { // TODO 自动生成的方法存根 FileInputStream is = new FileInputStream(src); FileOutputStream os = new FileOutputStream(dst); FileChannel Ichannel = is.getChannel(); FileChannel Ochannel = os.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (true) { int num = Ichannel.read(buffer); if (num == -1) { break; } buffer.flip();//Flips this buffer. The limit is set to the current position and thenthe position is set to zero. Ochannel.write(buffer); buffer.clear(); } Ichannel.close(); Ochannel.close(); is.close(); os.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); //fileOption(); //randomReadFile(); //pipedStream(); //bufferStream(); //bufferChar(); NIOReadAndWriteByCopyFile("G:/Java/hello3.text", "G:/Java/hello4.text"); } } 复制代码
src为文件读取路径,dst为写入文件路径,运行完毕后,会创建一个和src一样内容的dst文件 复制代码
这其中需要注意的:
-
在while循环中使用read()==-1来检查是否读取完毕
-
Buffer类的flip()和clear()
控制buffer状态的三个变量:
1. position:跟踪写了或者读取了多少数据,它指向的是下一个字节来自哪个位置 2. limit:代表还有多少数据可以读取或者多少空间可以写入,它的值小于等于capacity 3. capacity:代表缓冲的最大容量,一般新建一个缓冲区的时候,limit和capacity的值默认是相等的 复制代码
flip、clear这两个方法就是用来设置这些值的。
public final Buffer flip() { //一般从Buffer读取数据前调用 limit = position; position = 0; mark = -1; //取消标记 return this; public final Buffer clear() { //一般把数据写入Buffer前调用 position = 0; limit = capacity; mark = -1; return this; 复制代码
-
网络编程NIO(异步IO)
简单介绍一下异步IO
- 异步IO在读写数据时没有阻塞,一般的IO,read时会阻塞直至有数据可读,write时会阻塞直至有数据能写入。异步IO不但不会阻塞,还可以注册IO事件如数据可读、新连接等,事件发生时,系统会通知。
- 异步IO的另一大优势是:它允许同时大量的输入和输出执行IO。同步IO通常以来轮询,或者创建大量线程来处理。使用异步IO,可以监听任意数量的通道上的事件,不用轮询,也不用大量线程。
Selector(NIO的第三个核心对象)
- Selector是一个对象,它可以注册到很多Channel上,监听各个Channel上发生的事件,并且能够根据事件决定Channel读还是写。这样通过一个线程管理多个Channel,就可以处理大量连接了。
- 有了Selector的好处:可以利用一个线程来处理所有的channels,线程之间的切换对于操作系统来说代价很高,并且每个线程都会占用资源。所以,系统使用的线程越少越好。(但随着现在操作系统和CPU在多任务方面表现越来越好,k开销也随之减小,实际上,一个多核CPU,不使用多任务却是浪费CPU能力)
Selector对Channel感兴趣的事件有四种:
- Connect --SelectionKey.OP_CONNECT
- Accept --SelectionKey.OP_ACCEPT
- Read --SelectionKey.OP_READ
- Write --SelectionKey.OP_WRITE
- Channel触发一个事件,说明该事件已经Ready。因此当channel与server连接成功后,就是connect ready;server channel接受请求连接时处于accept ready;channel有数据可读时处于read ready;channel有数据可写时,处于write ready。(如果对多个事件感兴趣,就用or("|")操作符来连接)
SelectionKey
- 对register()的调用返回的是一个SelectionKey。SelectionKey代表这个通道在此Selector上的注册。当某个Selector通知你某个事件传入时,它是通过提供该事件的SelectionKey来进行的,SelectionKey还可以用户取消通道的注册。它的属性如下:
- The interest set (就是要选择的感兴趣的事件的集合)
- The ready set (通道已经准备就绪的集合)
- The Channel (获得注册的Channel)
- The Selector (获得注册的Selector)
- An attached object(optional) (一个对象或者更多信息attach到SelectionKey上,方便识别某个特定通道)
通过Selector选择通道
-
一旦通过Selector注册了一个或多个通道,就可以调用几个重载的select()方法,这些方法返回已经准备就绪的通道。
- int select():阻塞到至少有一个通道在你注册的事件上就绪
- int select(long timeout):和select一样,除了最长会阻塞timeout毫秒
- int selectNow():不会阻塞,不论什么通道就绪立即返回
-
一旦调用了select()方法,它会返回一个数值,表示一个或多个通道已就绪。你就可以通过selector.selectedKey()返回SelectionKey中就虚的channenl
-
某个线程调用select后阻塞了,也有办法使其从select返回,只要让其他线程在第一个线程调用select方法的那个对象上调用selector.wakeup,阻塞的线程会立马返回。
-
如果有其他线程调用wakeup,但却没有线程阻塞在select方法上,那么下个调用select的线程会立马wakeup。
-
用完Selector后调用close方法,它将关闭 Selector并使注册到该Selector下的所有SelectionKey无效,通道本身不会关闭。
3.9. BufferedInputStream和BufferedOutputStream
即使用buffer来提高IO的效率,普通的IO是一个字节一个字节读写,而是用buffer,就可以一次读写一大块数据
package cn.wh3t; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.RandomAccessFile; import java.io.Reader; public class AboutIO { public static void bufferStream() throws IOException { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello3.text"); byte[] bytes = new byte[(int)file.length()]; InputStream is = new BufferedInputStream(new FileInputStream(file),2*1024); //the total number of bytes read into the buffer, or -1 if there is no more data because the end ofthe stream has been reached. int size = is.read(bytes); System.out.println("大小:"+size+"内容:"+new String(bytes)); is.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); //fileOption(); //randomReadFile(); //pipedStream(); bufferStream(); } } 复制代码
大小:1595内容:如果你和许多人一样,你可能已经决定要少花点时间盯着手机看了。 这是个好主意:越来越多的证据表明,我们在我们的智能手机上耗费的时间正在干扰我们的睡眠、自尊、人际关系、记忆、注意力持续时间、创造力、生产力以及解决问题和决策的能力。 但令我们重新思考与这些设备的关系的,还有另一个原因。通过长期提高身体主要的应激激素——皮质醇的水平,我们的手机可能会威胁我们的健康,并缩短我们的寿命。 到目前为止,大多数关于手机生化效应的讨论都集中在多巴胺上,这是一种帮助我们形成习惯和上瘾的大脑化学物质。就像老虎机一样,智能手机和应用程序明显是为了触发多巴胺的释放而设计的,目的就是让我们难以放下手中的设备。 这种对我们多巴胺系统的操纵,正是许多专家认为我们正在对我们的手机产生行为上瘾的原因。但我们的手机对皮质醇的影响可能更令人担忧。 皮质醇是影响战逃决策的主要激素。它的释放会引发一些生理变化,比如血压、心率和血糖的飙升,这些变化会帮助我们对紧急的人身威胁做出反应并存活下来。 如果你的身体确实存在危险,比如一头公牛正在向你冲来,这些反应将可以挽救你的生命。但我们的身体也会释放皮质醇以应对情绪压力,在这种情况下,心率加快并没有多大好处,比如查看手机时发现老板发来的一封愤怒的邮件。 复制代码
关于设置buffer的大小,需要知道磁盘的每次读的块大小和其缓存大小,一边设置最优值。
BufferOutputStream基本一样。
- BufferedReader和BufferedWriter
与BufferedInputStream和BufferedOutputStream差不多,只不过面向实现的是字符流。
package cn.wh3t; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.RandomAccessFile; import java.io.Reader; public class AboutIO { public static void bufferChar() throws IOException { // TODO 自动生成的方法存根 File file = new File("G:/Java/hello3.text"); char[] chars = new char[(int)file.length()]; Reader reader = new BufferedReader(new FileReader(file)); //The number of characters read, or -1if the end of the streamhas been reached int size = reader.read(chars); System.out.println("大小:"+size+"内容:"+new String(chars)); reader.close(); } public static void main(String[] args) throws IOException { //writeByte2File(); //readFile2Bytes(); //writeChar2File(); //readFile2Char(); //byte2Char(); //fileOption(); //randomReadFile(); //pipedStream(); //bufferStream(); bufferChar(); } } 复制代码
大小:541内容:如果你和许多人一样,你可能已经决定要少花点时间盯着手机看了。 这是个好主意:越来越多的证据表明,我们在我们的智能手机上耗费的时间正在干扰我们的睡眠、自尊、人际关系、记忆、注意力持续时间、创造力、生产力以及解决问题和决策的能力。 但令我们重新思考与这些设备的关系的,还有另一个原因。通过长期提高身体主要的应激激素——皮质醇的水平,我们的手机可能会威胁我们的健康,并缩短我们的寿命。 到目前为止,大多数关于手机生化效应的讨论都集中在多巴胺上,这是一种帮助我们形成习惯和上瘾的大脑化学物质。就像老虎机一样,智能手机和应用程序明显是为了触发多巴胺的释放而设计的,目的就是让我们难以放下手中的设备。 这种对我们多巴胺系统的操纵,正是许多专家认为我们正在对我们的手机产生行为上瘾的原因。但我们的手机对皮质醇的影响可能更令人担忧。 皮质醇是影响战逃决策的主要激素。它的释放会引发一些生理变化,比如血压、心率和血糖的飙升,这些变化会帮助我们对紧急的人身威胁做出反应并存活下来。 如果你的身体确实存在危险,比如一头公牛正在向你冲来,这些反应将可以挽救你的生命。但我们的身体也会释放皮质醇以应对情绪压力,在这种情况下,心率加快并没有多大好处,比如查看手机时发现老板发来的一封愤怒的邮件。 复制代码
-
参考:
Java基础——Java IO详解
Java基础——Java NIO详解(一)
Java基础——Java NIO详解(二)
Java NIO 简明教程
转载于:https://juejin.im/post/5d0857296fb9a07ef06f95a3