java面试初级篇-输入输出流

输入输出流


Java中如何实现序列化,有什么意义? 


答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。

要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。

 

Java中有几种类型的流?


答:字节流和字符流。字节流继承于InputStreamOutputStream,字符流继承于ReaderWriter。在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。关于JavaI/O需要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。另外Java中的流不同于C#的是它只有一个维度一个方向。

 

编程实现文件拷贝。(这个题目在笔试的时候经常出现,下面的代码给出了两种实现方案)

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

 

public final class MyUtil {

 

    private MyUtil() {

        throw new AssertionError();

    }

    public static void fileCopy(String source, String target) throws IOException {

        try (InputStream in = new FileInputStream(source)) {

            try (OutputStream out = new FileOutputStream(target)) {

                byte[] buffer = new byte[4096];

                int bytesToRead;

                while((bytesToRead = in.read(buffer)) != -1) {

                    out.write(buffer, 0, bytesToRead);

                }

            }

        }

    }

 

    public static void fileCopyNIO(String source, String target) throws IOException {

        try (FileInputStream in = new FileInputStream(source)) {

            try (FileOutputStream out = new FileOutputStream(target)) {

                FileChannel inChannel = in.getChannel();

                FileChannel outChannel = out.getChannel();

                ByteBuffer buffer = ByteBuffer.allocate(4096);

                while(inChannel.read(buffer) != -1) {

                    buffer.flip();

                    outChannel.write(buffer);

                    buffer.clear();

                }

            }

        }

    }

}

 

写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。 


import java.io.BufferedReader;

import java.io.FileReader;

 

public final class MyUtil {

 

    // 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯)

    private MyUtil() {

        throw new AssertionError();

    }

 

    /**

     * 统计给定文件中给定字符串的出现次数

     *

     * @param filename  文件名

     * @param word 字符串

     * @return 字符串在文件中出现的次数

     */

    public static int countWordInFile(String filename, String word) {

        int counter = 0;

        try (FileReader fr = new FileReader(filename)) {

            try (BufferedReader br = new BufferedReader(fr)) {

                String line = null;

                while ((line = br.readLine()) != null) {

                    int index = -1;

                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {

                        counter++;

                        line = line.substring(index + word.length());

                    }

                }

            }

        } catch (Exception ex) {

            ex.printStackTrace();

        }

        return counter;

    }

 

}

 

如何用Java代码列出一个目录下所有的文件?


答:

如果只要求列出当前文件夹下的文件,代码如下所示:

 

import java.io.File;

 

class Test12 {

 

    public static void main(String[] args) {

        File f = new File("/Users/Hao/Downloads");

        for(File temp : f.listFiles()) {

            if(temp.isFile()) {

                System.out.println(temp.getName());

            }

        }

    }

}

 

1. 下面哪个流类属于面向字符的输入流?

A. BufferedWriter

B. FileInputStream

C. ObjectInputStream

D. InputStreamReader

 

答案:D

解析:Java  IO 操作中有面向字节(Byte)和面向字符(Character)两种方式。

面向字节的操作为以 8 位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是 InputStream  OutputStream 的子类。

面向字符的操作为以字符为单位对数据进行操作,在读的时候将二进制数据转为字符,在写的时候将字符转为二进制数据,这些类都是 Reader  Writer 的子类。

总结:以 InputStream(输入)/OutputStream(输出)为后缀的是字节流;以Reader(输入)/Writer(输出)为后缀的是字符流。

扩展:Java 流类图结构,一目了然,解决大部分选择题:

 java面试初级篇-输入输出流

 

2. 阅读 Shape 和 Circle 两个类的定义。在序列化一个 Circle 的对象 circle 到文件时,下面哪个字段会被保存到文件中?

class Shape {

 

       public String name;

}

 

class Circle extends Shape implements Serializable{

 

       private float radius;

 

       transient int color;

 

       public static String type = "Circle";

 

}

A. name B. radius C. color D. type

 

答案:B

 

 

3. 什么是 Java 序列化,如何实现 Java 序列化?


序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

 

序列化的实现:将需要被序列化的类实现 Serializable 接口,该接口没有需要实现的方法, implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。



文章推荐

1

java面试中级篇-Servlet与JSP

2

java面试初级篇-java异常体制

3

java面试中级篇-数据库常见面试题

4

java面试中级篇-SQL优化

5

java面试初级篇-java集合