‘壹’ java io 阻塞底层是如何实现的nio底层是如何实现非阻塞的
说实话,在这个问题前我没听说过“nio”这个名字。
刚才上网查了一下,我觉得网上有一些资料还是不错。
在网络上使用“java nio”作为关键字搜索。我就搜索到一个文章,稍微读了一下,有一些小收获。
文章名字大致为《java nio原理和使用》,不知道是否对你有用。
以上我的回答,仅供参考。
‘贰’ java的IO流中可以通过自定义一个数组来存储数据,为什么还要使用缓存区呢
IO流自定义字节流的缓冲区:
思路:BufferedInputStream类中read()方法的工作原理
1)先一个一个从字节流中读取字节,读取一定量(自定义)之后,存储在一个字节数组(缓冲区)(FileInputStream.read(byte[] b)),并获得存储数量(read方法的返回值)。
2)一个一个字节返回,返回一个,存储数量减1,然后指针往后移一位,准备取下一个。
3)如果存储数量为0 ,代表当前数组中所有数据已经全部取完,此时再来一次读取(read(byte[] b)),再获得此次存储数量。
4)如果存储数量(即read方法返回-1),代表读到文件末尾,返回-1。
因此,需要用到以下几个变量:
读取的字节数量,指向数组中准备取哪一个的指针,将要返回的字节变量。
‘叁’ 学java的io的时候这部分不懂
FileReader 是文件读取流,通俗讲读取文件用的,工作原理不需要懂,知道干什么的就行了,
setText是写入文件
‘肆’ 求高手点拨“Java io流”部分的知识详细原理辨析。
分析,你应该是tcp 你tcp连接的话,tcp的底层io不就是一个io流管道!实际上就是向一个地方,一个方向写。不关你是几个outputStream对象,在同一个tcp连接,对应的都应该写到一个客户端,这个是有你只要一个DataInputStream接受不就行了,对于多个tcp连接,每个客户端都有一个DataiNPUTsTREAM
‘伍’ 如何学好java的io
首先先搞懂JavaSE的部分,Swing和swt部分就可以少看或不看,因为现在用的比较少。重点是看懂Java中的面向对象、集合框架、JDBC、异常、IO、线程和网络编程。JavaSE搞定后再学习Servlet、JSP,然后才是经典的Struts2、Hibernate和Spring,学习框架时重点理解框架的运行原理,甚至可以尝试自己写个轻量级的框架。理解运行原理的最好方法就是阅读源代码,还是要感谢Java中的开源项目。这期间还要多找各种大小的项目去完成,不一定要大,但是要精致,功能要完整,这样可以练习所学知识,并且可以在做项目中发现自己的知识体系中不足的地方。关于看视频,我不推荐,很多同学一天到晚就知道看视频,殊不知,编程真理在于“练习,练习,不停练习”!
再补充下:当学习Java的期间,会碰到各种各样的异常,请积累这些异常信息,以及如何出现的异常和如何处理的,因为java中常见的异常就那么几种,积累的多了,处理问题的能力就提高,这样水平会提高的很快!
-----------------2015年1月5日修改---------------
这个答案最开始是11年回答的,不少留言的同学问现在这个答案是否还有效,答案是依然有效。因为这几年的发展,从招聘的角度看,使用 Java 的IT 的公司对技术的要求变化不大,依然要求你有扎实的 JavaSE 功底,会使用常用的框架。
SpringMVC 这几年的占有率迅速的提高,可能之后会取代 Struts2,但是无论怎么变化,这些还都是 MVC 模式,理解了这个模式,上手任何的 MVC框架都应该很快。
企业需要的变化还体现在大数据方面,因为 Hadoop 的流行,Java 的应用场景又多了一个。所以,不喜欢 web 的可以考虑学习大数据方面的知识。
另一个流行的场景自然就是 Android,学习 Android 依然需要你有 JavaSE 的底子+HTTP 协议的理解,再配合上 Linux 的知识就可以开始了。
再说下找项目的问题,初学者可能会碰到不知道做什么的问题,其实最开始大家都是从模仿开始的,例如你学会了 jsp+Servlet,那就可以模仿一个 v2ex 这样的论坛出来。学会了 SpringMVC,那就试着将论坛的代码重构,提供restful接口供客户端访问(Android、IOS 、web 等)。论坛做的没难度了,那就模仿一个团购网站,依然是不一定要做全部的功能,但是做出的功能要稳定,要精致。或者一个微信公众平台的开发都是不错的项目。
初学者看源代码有的人推荐看 Struts2、spring 的,但是我相信10个初学者9个看不懂,那就从简单的开始,例如 Apache 的 Commons 库,例如 lang、dbutils、io 等,这些都是非常不错的代码,类的数量不多而且质量也不错,这些看懂之后,你的基础水平增长的不是一点点。
再次提醒初学者,学习编程没有你想的那么简单,必须要多练习,多思考,最主要的是你对这个有兴趣。现在不少网站和媒体都宣传1个月学会前端、3个月入职 BAT 的口号,那也就是口号而已,别太认真。这条路没有捷径,写你的代码就是了!
暂时就这么多,
‘陆’ java-io流缓冲区的小疑问
你问的问题很有研究性,要处理的文件很小的时候这样的确看不出来你说的区别,缓冲区是个可以重用的内存区,这个主要是用于CPU提高读取文件的效率,而CPU的速度是远远高与内存的,假设你没有这个缓冲区的话,CPU就会要不停的读取文件,当在读取较大的文件时,这样处理效率是不是很低呢?内存速度慢,你这样一个字节一个字节的送的话是不是整体的效率都低了啊?当你有缓冲的时候CPU在等缓冲区写满时是不是可以处理其它的信息呢?
‘柒’ java的IO类那么多,应该掌握哪几个
IO包中绝大部分的类都是由以下四个类直接或间接继承来的
InputStream OutputStream Reader 还有Writer
其中InputStream和OutputStream代表输入流和输出流,也就是字节流的输入和输出,他们定义了如何读取和写入字节和字节数组,所以说基本上所有XXXInputStream和XXXOutputStream都是针对字节进行操作的
比如说FileInputStream,它可以以流的形式读取一个文件,或者StringBufferInputStream,它以流的形式读取一个字符串,所有的子类都是不同领域的应用罢了
而Reader和Writer是在输入输出流之上的更高级的字符级别的输入输出,称为读取器和写入器,他们直接读取和写入字符(字符串)数据而不是字节(字节数组),比如你有一个文本文件就可以使用FileReader这个类来读取里面的文本,还有PrintWriter是用来输出的写入器,System.out的那个out返回的就是一个PrintWirter的内部实现PrintOutputStream
其实具体类用的比较多的就是File开头的String开头的和Object开头的,Object开头的是用来序列化读取的
IO包并不难,别被吓到了,掌握好他们之间的继承关系,就可以很容易了解
‘捌’ Java中IO缓冲区的原理是什么
如果是边读边写,就会很慢,也伤硬盘。缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入,类似数据库的批量操作,这样效率比较高。
调用I\O操作的时候,实际上还是一个一个的读或者写,关键就在,CPU只有一个,不论是几个核心。CPU在系统调用时,会不会还要参与主要操作?参与多次就会花更多的时间。
系统调用时,若不用缓冲,CPU会酌情考虑使用 中断。此时CPU是主动地,每个周期中都要花去一部分去询问I\O设备是否读完数据,这段时间CPU不能做任何其他的事情(至少负责执行这段模块的核不能)。所以,调用一次读了一个字,通报一次,CPU腾出时间处理一次。
而设置缓冲,CPU通常会使用 DMA 方式去执行 I\O 操作。CPU 将这个工作交给DMA控制器来做,自己腾出时间做其他的事,当DMA完成工作时,DMA会主动告诉CPU“操作完成”。这时,CPU接管后续工作。在此,CPU 是被动的。DMA是专门 做 I\O 与 内存 数据交换的,不仅自身效率高,也节约了CPU时间,CPU在DMA开始和结束时做了一些设置罢了。
所以,调用一次,不必通报CPU,等缓冲区满了,DMA 会对C PU 说 “嘿,伙计!快过来看看,把他们都搬走吧”。
综上,设置缓冲,就建立了数据块,使得DMA执行更方便,CPU也有空闲,而不是呆呆地候着I\O数据读来。从微观角度来说,设置缓冲效率要高很多。尽管,不能从这个程序上看出来。 几万字的读写\就能看到差距
‘玖’ Java.IO中 为什么带缓冲的字节输入输出流速度比不带缓冲的速度快
原理:通过将字节缓冲到内存然后到磁盘比直接通过程序输出到磁盘要快。
缓冲:就是通过缓冲流操作字节读或写入内存。
在内存中就是以流的形式输出。
总结:从内存读取数据比从磁盘读取数据要快。
‘拾’ java.io的Java流输入输出原理
Java把这些不同来源和目标的数据都统一抽象为数据流。Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象。
在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流。 按流向分:
输入流: 程序可以从中读取数据的流。
输出流: 程序能向其中写入数据的流。
按数据传输单位分:
字节流: 以字节为单位传输数据的流
字符流: 以字符为单位传输数据的流
按功能分:
节点流: 用于直接操作目标设备的流
过滤流: 是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。 JDK所提供的所有流类位于java.io包中,都分别继承自以下四种抽象流类。
InputStream:继承自InputStream的流都是用于向程序中输入数据的,且数据单位都是字节(8位)。
OutputStream:继承自OutputStream的流都是程序用于向外输出数据的,且数据单位都是字节(8位)。
Reader:继承自Reader的流都是用于向程序中输入数据的,且数据单位都是字符(16位)。
Writer:继承自Writer的流都是程序用于向外输出数据的,且数据单位都是字符(16位)。 BufferedInputStream BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。 BufferedOutputStream 该类实现缓冲的输出流。 BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 ByteArrayInputStream ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。 ByteArrayOutputStream 此类实现了一个输出流,其中的数据被写入一个 byte 数组。 CharArrayReader 此类实现一个可用作字符输入流的字符缓冲区。 CharArrayWriter 此类实现一个可用作 Writer 的字符缓冲区。 Console 此类包含多个方法,可访问与当前 Java 虚拟机关联的基于字符的控制台设备(如果有)。 DataInputStream 数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。 DataOutputStream 数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。 File 文件和目录路径名的抽象表示形式。 FileDescriptor 文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。 FileInputStream FileInputStream 从文件系统中的某个文件中获得输入字节。 FileOutputStream 文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。 FilePermission 此类表示对文件和目录的访问。 FileReader 用来读取字符文件的便捷类。 FileWriter 用来写入字符文件的便捷类。 FilterInputStream FilterInputStream 包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。 FilterOutputStream 此类是过滤输出流的所有类的超类。 FilterReader 用于读取已过滤的字符流的抽象类。 FilterWriter 用于写入已过滤的字符流的抽象类。 InputStream 此抽象类是表示字节输入流的所有类的超类。 InputStreamReader InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。 LineNumberInputStream 已过时。此类错误假定字节能充分表示字符。