常见的IO流面试试题

常见的IO流面试试题什么是比特(Bit)?什么是字节(Byte)?什么是字符(Char)?以及他们的区别?Bit位,是计算机最小的二进制单位,取0或1,主要用于计算机操作。Byte字节,是数据的最小单位,由8位bit组成,取值(-128-127),主要用于计算机操作数据。Char字符,是用户可读写的最小单位,由16位bit(2个byte)组成,取值(0-65535),主要用于用户操数数据。什么是IO流?IO流就是以流的方式进行输入输出主要用来处理设备之间的传输,文件的上传,下载和复制流分输入和输出,输入.

大家好,欢迎来到IT知识分享网。常见的IO流面试试题"

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流练习

  1. 读写原始数据,一般采用什么流?(AC )
    A. InputStream B. DataInputStream C. OutputStream D. BufferedInputStream
  2. 为了提高读写性能,可以采用什么流?( DF)
    A. InputStream B. DataInputStream C. BufferedReader D. BufferedInputStream E. OutputStream F. BufferedOutputStream
  3. 对各种基本数据类型和String类型的读写,采用什么流?( AD)
    A. DataInputStream B. BufferedReader C. PrintWriter D. DataOutputStream E. ObjectInputStream F. ObjectOutputStream
  4. 能指定字符编码的I/O流类型是:(BH )
    A. Reader B. InputStreamReader C. BufferedReader D. Writer E. PrintWriter
    F. ObjectInputStream G. ObjectOutputStream H. OutputStreamWriter
  5. File类型中定义了什么方法来判断一个文件是否存在?( D)
    A. createNewFile B. renameTo C. delete D. exists
  6. File类型中定义了什么方法来创建一级目录?( CD)
    A. createNewFile B. exists C. mkdirs D. mkdir
    File类的mkdir方法根据抽象路径创建目录;File类的mkdirs方法根据抽象路径创建目录,包括创建必需但不存在的父目录
  7. 对文本文件操作用什么I/O流?(AD )
    A. FileReader B. FileInputStream C. RandomAccessFile D. FileWriter
  8. 在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);
  9. 创建一个TCP客户程序的顺序是:(DACBE )
    A. 获得I/O流 B. 关闭I/O流 C. 对I/O流进行读写操作 D. 建立socket E. 关闭socket
  10. 创建一个TCP服务程序的顺序是:(BCADEGF )
    A. 创建一个服务线程处理新的连接
    B. 创建一个服务器socket
    C. 从服务器socket接受客户连接请求
    D. 在服务线程中,从socket中获得I/O流
    E. 对I/O流进行读写操作,完成与客户的交互
    F. 关闭socket
    G. 关闭I/O流
  11. Java UDP编程主要用到的两个类型是:( BD)
    A. UDPSocket
    B. DatagramSocket
    C. UDPPacket
    D. DatagramPacket
  12. 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://yundeesoft.com/21751.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信