大家好,欢迎来到IT知识分享网。
IO流
1. 什么是比特(Bit)?什么是字节(Byte)?什么是字符(Char)?以及他们的区别?
Bit 位,是计算机最小的二进制单位 ,取0或1,主要用于计算机操作。
Byte 字节,是数据的最小单位,由8位bit组成,取值(-128-127),主要用于计算机操作数据。
Char 字符,是用户可读写的最小单位,由16位bit(2个byte)组成,取值(0-65535),主要用于用户操数数据。
2. 什么是IO流?
IO流就是以流的方式进行输入输出
主要用来处理设备之间的传输,文件的上传,下载和复制
流分输入和输出,输入流从文件中读取数据存储到进程中,输出流从进程中读取数据然后写入到目标文件。
3. 流按照传输的单位怎么分类?分成哪两种流,并且他们的父类叫什么?说一下常用的IO流?
按照传输单位分为字符流和字节流。
字节流的父类是:InputStream,OutputStream
字节流的父类是:Reader,Writer
常用的IO流有:
输入–>InputStream:FileInputStream,BufferedInputStream
输出–>OutputStream:FileOutputStream,BufferedOutputStream
Reader: BufferedReader
Writer:BufferedWriter
4. 流按照传输的方向怎么分类?
按照传输方向主要分为输入流(InputStream)和输出流(OutputStream)
5. 流按实现功能怎么分?
按照功能分为:节点流OutputStream、处理流 OutputStreamWriter
节点流 :直接与数据源相连,用于输入或输出
处理流:在节点流的基础上对之进行加工,进行一些功能的扩展
6. BufferedReader属于哪种流,它主要是用来做什么的,它里面有那些经典的方法?
属于处理流中的缓冲流,可以将读取的内容存在内存里面,有readLine()方法读取一行文本,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
这种处理流的构造器需要传入字点流。
FileInputStream fil = new FileInputStream("D:\\0823.txt");
InputStreamReader inp =new InputStreamReader(fil);
BufferedReader buf = new BufferedReader(inp);
String data=null;
//readLine()读一行文字
while ((data=buf.readLine())!=null){
System.out.println(data);
}
buf.close();
7. InputStreamReader类
是字节流通向字符流的桥梁,封裝了InputStream在里头, 它以较高级的方式,一次读取一个一个字符,以文本格式输入 / 输出,可以指定编码格式;
InputStreamReader isr = newInputStreamReader(new FileInputStream("ming.txt"));
while((ch =isr.read())!=-1){
System.out.print((char)ch);
}
8. FileInputStream和FileOutputStream是什么?
在拷贝文件操作的时候,经常用到的两个类。这两个流比较小,一般在处理小文件的时候,他们性能表现还不错,在大文件的时候,最好使用BufferedInputStream(或BufferedReader)和BufferedOutputStream(或BufferedWriter)
9. 如果要对字节流进行大量的从硬盘读取,要用那个流,为什么?
BufferedInputStream 使用缓冲流能够减少对硬盘的损伤
10.System.out.println()是什么?
println是PrintStream的一个方法。Out是一个静态PrintStream类型的成员变量,system是一个java.lang包中的类,用于和底层的操作系统进行交互。
11.如果我要打印出不同类型的数据到数据源,那么最适合的流是那个流,为什么?
Printwriter 可以打印各种数据类型
PrintWriter和PrintStream类似,只不过PrintStream是针对字节流的,而PrintWriter是针对字符流的。
public static void main(String[] args) throws FileNotFoundException {
String s1="我们"+"\n";
String s2="you"+"\n";
PrintWriter writer = new PrintWriter("D:\\01.txt");
writer.println(s1);
writer.println(s2);
writer.close();
}
12.怎么样把我们控制台的输出改成输出到一个文件里面,这个技术叫什么?
SetOut(printWriter,printStream)重定向
13.怎么样把输出字节流转换成输出字符流,说出它的步骤?
使用转换处理流OutputStreamWriter 可以将字节流转为字符流
New OutputStreamWriter(new FileOutputStream(File file));
14.把包括基本类型在内的数据和字符串按顺序输出到数据源,或者按照顺序从数据源读入,一般用哪两个流?
DataInputStream DataOutputStream
15.把一个对象写入数据源或者从一个数据源读出来,用哪两个流?
ObjectInputStream ObjectOutputStream
16.什么是序列化和反序列化,实现对象序列化需要做哪些工作?
对象序列化是将对象以二进制的形式保存在硬盘上或者传输到网络;而反序列化则是将二进制的文件转化为对象读取。
Jre本身就提供了序列化支持,我们可以调OutputStream的writeObject方法来做,如果要让java 帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。
serializable接口是一个mini接口,其中没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。
如果不想让字段放在硬盘上就加transient。
17.在实现序列化接口是时候一般要生成一个serialVersionUID字段,它叫做什么,一般有什么用?
是版本号,要保持版本号的一致 来进行序列化,主要是为了防止序列化出错
实现Serializable接口的目的是为类可持久化,比如在网络传输或本地存储,为系统的分布和异构部署提供先决条件。若没有序列化,现在我们所熟悉的远程调用,对象数据库都不可能存在
具体序列化的过程是这样的:
序列化操作时会把系统当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会自动检测文件中的serialVersionUID,判断它是否与当前类中的serialVersionUID一致。如果一致说明序列化文件的版本与当前类的版本是一样的,可以反序列化成功,否则就失败;
serialVersionUID有两种显示的生成方式:
一是默认的1L,比如:private static final long serialVersionUID = 1L;
二是根据包名,类名,继承关系,非私有的方法和属性,以及参数,返回值等诸多因子计算得出的,极度复杂生成的一个64位的哈希字段。基本上计算出来的这个值是唯一的。比如:private static final long serialVersionUID = xxxxL;
18.请问你在什么情况下会在你得java代码中使用可序列化? 如何实现java序列化?
把一个对象写入数据源或者从一个数据源读出来,使用可序列化,需要实现Serializable接口
19.InputStream里的read()返回的是什么,read(byte[] data)是什么意思,返回的是什么值?
read()返回的是所读取的字节的int型(范围0-255)
read(byte [ ] data)将读取的字节储存在这个数组, 返回的就是传入数组参数个数
Read 字节读取字节 字符读取字符
20.OutputStream里面的write()是什么意思?write(byte b[], int off, int len)这个方法里面的三个参数分别是什么意思?
write将指定字节传入数据源
Byte b[ ]是byte数组,b[off]是传入的第一个字符,我的理解就是数组的下标,b[off+len-1]是传入的最后的一个字符 ,len是数组的实际长度
21.流一般需要不需要关闭?怎么关闭?一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是怎么关闭的?
流一旦打开就必须关闭,要使用close方法关闭,一般放在finally语句块中(finally 语句一定会执行)执行。
多个流互相调用只关闭最外层的流即可。
22. io流怎样读取文件的?
使用File对象获取文件路径;
通过字符流Reader加入文件;
使用字符缓存流BufferedReader处理Reader;
再定义一个字符串,循环遍历出文件。
代码如下:
public static void main(String[] args) {
//1.获取文件路径
File file = new File("D:\\28.txt");
try {
//2.Reader加入文件
FileReader reader = new FileReader(file);
//3.使用BufferedReader来处理Reader
BufferedReader buf = new BufferedReader(reader);
//4.定义一个字符串,循环遍历出文件
String data=null;
while ((data=buf.readLine())!=null){
System.out.println(data);
}
buf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
23.用什么把对象动态的写入磁盘中,写入要实现什么接口。
ObjectInputStream,需要实现Serializable接口
24. FileInputStream 创建详情,就是怎样的创建不报错,它列出了几种形式?
FileInputStream是InputStream的子类,通过接口定义,子类实现创建FileInputStream,
25.用io流中的技术,指定一个文件夹的目录,获取此目录下的所有子文件夹路径
通过递归的方法来获取该目录下的所有的文件
public static void showFile(String pathName){
File f1=new File(pathName);
//判断文件夹是否存在
boolean flag1=f1.isDirectory();
//选择某个文件下面的所有文件
if(flag1){
//如果是文件夹
File[] files=f1.listFiles();
for (int i=0;files!=null && i<files.length;i++){
boolean flag2=files[i].isDirectory();
if (flag2){
//是文件夹
showFile(files[i].getPath());
}else{
String path =f1.getPath();
System.out.println("获取普通文件路径为:"+path);
}
}
}else {
//如果不是一个文件夹
String filepath =f1.getPath();
System.out.println("获取普通文件路径为:"+filepath);
}
}
public static void main(String[] args) {
fileDemo1.showFile("D:\\");
}
}
26.PrintStream、BufferedWriter、PrintWriter的比较?
PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream后进行输出。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream
BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符,数组和字符串的高效写入。通过write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去。并且BufferedWriter只能对字符流进行操作。如果要对字节流操作,则使用BufferedInputStream。
PrintWriter的println方法自动添加换行,不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生,PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush);
27.什么是Filter流
Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。
28.有哪些可用的Filter流?
在java.io包中主要有4个可用的filterStream。两个字节filterStream,两个字符filterStream。分别是FilterInputStream,FilterOutputStream,FilterReader and FilterWriter。这些类是抽象类,不能被实例化。
有些Filter流的子类:
LineNumberInputStream给目标文件增加行号
DataInputStream有些特殊的方法如readInt(),readDouble()和readLine()等可以读取一个int,double和一个string一次性的
BufferedInputStream增加性能
PushbackInputStream推送要求的字节到系统中
29.SequenceInputStream的作用
这个类的作用是将多个输入流合并成一个输出流,通过SequenceInputStream类包装后形成新的一个总的输入流。在拷贝多个文件到一个目标文件的时候是非常有用的。可以使用很少的代码实现。
30.PrintStream和PrintWriter
它们两个的功能相同,但是属于不同的分类。字节流和字符流,它们都有println()方法。
31.在拷贝的时候,哪一种流能提升更多的性能?
在字节流的时候,使用BufferedInputStream和BufferedOutputStream。
在字符流的时候,使用BufferedReader和BufferedWriter
32.管道流
有四种管道流,PipedInputStream,PipedOutputStream,PipedReader和PipedWriter。在多个线程或进程中传递数据的时候管道流非常有用。
PipedOutputStream、PipedWriter 是写入者/生产者/发送者;
PipedInputStream、PipedReader 是读取者/消费者/接收者。
33.RandomAccessFile
它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。DataInputStream和DataOutStream有的方法,在RandomAccessFile都存在
IO流练习
- 读写原始数据,一般采用什么流?(AC )
A. InputStream B. DataInputStream C. OutputStream D. BufferedInputStream - 为了提高读写性能,可以采用什么流?( DF)
A. InputStream B. DataInputStream C. BufferedReader D. BufferedInputStream E. OutputStream F. BufferedOutputStream - 对各种基本数据类型和String类型的读写,采用什么流?( AD)
A. DataInputStream B. BufferedReader C. PrintWriter D. DataOutputStream E. ObjectInputStream F. ObjectOutputStream - 能指定字符编码的I/O流类型是:(BH )
A. Reader B. InputStreamReader C. BufferedReader D. Writer E. PrintWriter
F. ObjectInputStream G. ObjectOutputStream H. OutputStreamWriter - File类型中定义了什么方法来判断一个文件是否存在?( D)
A. createNewFile B. renameTo C. delete D. exists - File类型中定义了什么方法来创建一级目录?( CD)
A. createNewFile B. exists C. mkdirs D. mkdir
File类的mkdir方法根据抽象路径创建目录;File类的mkdirs方法根据抽象路径创建目录,包括创建必需但不存在的父目录 - 对文本文件操作用什么I/O流?(AD )
A. FileReader B. FileInputStream C. RandomAccessFile D. FileWriter - 在unix服务器www.openlab.com.cn上提供了基于TCP的时间服务应用,该应用使用port为13。创建连接到此服务器的语句是:(A )
A. Socket s = new Socket(“www.openlab.com.cn”, 13);
B. Socket s = new Socket(“www.openlab.com.cn:13”);
C. Socket s = accept(“www.openlab.com.cn”, 13); - 创建一个TCP客户程序的顺序是:(DACBE )
A. 获得I/O流 B. 关闭I/O流 C. 对I/O流进行读写操作 D. 建立socket E. 关闭socket - 创建一个TCP服务程序的顺序是:(BCADEGF )
A. 创建一个服务线程处理新的连接
B. 创建一个服务器socket
C. 从服务器socket接受客户连接请求
D. 在服务线程中,从socket中获得I/O流
E. 对I/O流进行读写操作,完成与客户的交互
F. 关闭socket
G. 关闭I/O流 - Java UDP编程主要用到的两个类型是:( BD)
A. UDPSocket
B. DatagramSocket
C. UDPPacket
D. DatagramPacket - TCP/IP是一种:( B)
A. 标准
B. 协议
C. 语言
D. 算法
java IO分类
Java BIO: 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
Java NIO: 同步非阻塞,服务器实现模式为一个请求一个线程,即当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。
Java AIO(NIO.2): 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
名词解释
同步:指的是用户进程触发IO操作需要等待或者轮询的去查看IO操作执行完成才能执行其他操作.这种方式性能比较差,只有一些对数据安全性要求比较高的场景中才会使用.
异步:异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知(异步的特点就是通知)
阻塞:所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止
非阻塞:非阻塞状态下, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待
BIO、NIO、AIO适用场景分析
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
Java NIO和IO的主要区别
面向流与面向缓冲. Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。
阻塞与非阻塞IO Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
选择器(Selectors) Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
原文出处:https://blog.csdn.net/CSDN_Terence/article/details/89513420
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/21751.html