Java习题解答11

1.Java中流的分类有哪些?

流动方向:一般分为输入流(InputStream:System.in)和输出流 (PrintStream:System.out)两类。程序可以用输出流从文件中读取数据。而针对键盘只有输入流,针对屏幕只有输出流。

读取类型: 一般分为字节流(InputStream:System.in)和字符流 (字符流对象:new InputStreamReader(System.in))。字节流是从InputStream和OutputStream派生出来的一个系列类,它以字节(byte)为基本处理单位。它们的继承关系如下(缩进的层次表示继承关系):

java.io.InputStream
    java.io.FileInputStream
    java.io.PipedInputStream
    java.io.ObjectInputStream
    java.io.ByteArrayInputStream
    java.io.SequenceInputStream
    java.io.FilterInputStream
        java.io.DataInputStream
        java.io.BufferedInputStream
        java.io.PushbackInputStream

java.io.OutputStream

发生源头: 分为节点流(直接操作目标设备对应的流,如文件流,标准输入输出流)和过滤流类(继承带有关键字Filter的流用于包装操作节点流,方便读写各种类型的数据)

2.字节流InputStream和OutputStream的子类分别有哪些?请举例说明其应用场景。与其对应的字符流分别有哪些?

(1)AudioInputStream :音频输入流是具有指定音频格式和长度的输入流。
e.g. 获取音频输入流的方式:

 AudioInputStream a = NULL;
  a = AudioSystem.getAudioInputStream(new File(fileName));//获取音频输入流

(2)ByteArrayInputStream&ByteArrayOutputStream :A ByteArrayInputStream包含一个内部缓冲区,其中包含可以从流中读取的字节。 内部计数器跟踪read方法要提供的下一个字节。
关闭ByteArrayInputStream没有任何效果。 在关闭流之后,可以调用此类中的方法,而不生成IOException 。
该类实现了将数据写入字节数组的输出流。 当数据写入缓冲区时,缓冲区会自动增长。 数据可以使用toByteArray()和toString() 。
关闭ByteArrayOutputStream没有任何效果。 该流中的方法可以在流关闭后调用,而不生成IOException 。
e.g.

import java.io.*;
public class ByteArrayStream {
     
   public static void main(String[] args){
     
     byte[] b = "hello".getBytes(); 
     ByteArrayInputStream bais = new ByteArrayInputStream(b); 
     int n =0;
     while((n = bais.read())!=-1){
     
        System.out.print((char)n); //hello
     }
   }
}


import java.io.*;
public class ByteArrayStream {
     
 public static void main(String[] args){
     
  byte[] b = "hello".getBytes(); 
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  baos.write(b, 0, b.length);
  System.out.println(new String(baos.toByteArray()));
 }
}

e.g. https://www.runoob.com/java/java-bytearrayinputstream.html

(3)FileInputStream(FileReader)& FileOutputStream(FileWriter) :
A FileInputStream从文件系统中的文件获取输入字节。 什么文件可用取决于主机环境。
FileInputStream用于读取诸如图像数据的原始字节流。 要阅读字符串,请考虑使用FileReader 。
文件输出流是用于将数据写入到输出流File或一个FileDescriptor 。 文件是否可用或可能被创建取决于底层平台。 特别是某些平台允许一次只能打开一个文件来写入一个FileOutputStream (或其他文件写入对象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。
FileOutputStream用于写入诸如图像数据的原始字节流。 对于写入字符流,请考虑使用FileWriter 。
e.g.

package chap14_2;
import java.io.*;
public class OpenFile {
     
    public static void main(String args[]) throws IOException{
     
        try{
                                             //创建文件输入流对象
            FileInputStream  rf = new FileInputStream("OpenFile.java");
            int n=512,c=0;
            byte buffer[] = new byte[n];
            while ((c=rf.read(buffer,0,n))!=-1 ){
        //读取输入流
                System.out.print(new String(buffer,0,c));
            }            
            rf.close();                            //关闭输入流
        }
        catch (FileNotFoundException ffe){
     
            System.out.println(ffe);}
        catch (IOException ioe){
     
            System.out.println(ioe);
        }
    }
}

import java.io.*;
public class Write1 {
     
    public static void main(String args[]){
     
        try{
     
            System.out.print("Input: ");
            int count,n=512;
            byte buffer[] = new byte[n];
            count = System.in.read(buffer);        //读取标准输入流
            FileOutputStream  wf = new FileOutputStream("Write1.txt");
                                                   //创建文件输出流对象
            wf.write(buffer,0,count);              //写入输出流
            wf.close();                            //关闭输出流
            System.out.println("Save to Write1.txt!");
        }
        catch (FileNotFoundException ffe){
     
            System.out.println(ffe);}
        catch (IOException ioe){
     
            System.out.println(ioe);} }
}

(4)FilterInputStream(FilterReader)&FilterOutputStream(FilterWriter) :
FilterInputStream包含一些其他输入流,它用作其基本的数据源,可能会沿途转换数据或提供附加功能。 FilterInputStream本身简单地覆盖了所有InputStream的方法, InputStream版本将所有请求传递给包含的输入流。 FilterInputStream的FilterInputStream可以进一步覆盖这些方法中的一些,并且还可以提供附加的方法和领域。
这个类是过滤输出流的所有类的超类。 这些流位于已经存在的输出流( 底层输出流) 之上 ,它使用它作为数据的基本接收器,但是可能沿着数据方向转换或提供附加功能。
类FilterOutputStream本身就简单地覆盖了所有OutputStream的方法, OutputStream版本将所有请求传递给底层输出流。 FilterOutputStream的FilterOutputStream可以进一步覆盖这些方法中的一些,并提供其他方法和字段。
注:不能访问 FilterInputStream 的构造方法,它是受保护的构造方法,但可以使用它的子类FilterInputStream filter=new BufferedInputStream(fis);
(5)ObjectInputStream&ObjectOutputStream :
序列化&反序列化 :将实现了Seriallizable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象。
使用ObjectInputStream类和ObjectOutputStream类
e.g.

import java.io.*;
 public class Student implements Serializable {
      //序列化
    int number=1;
    String name;
    Student(int number,String n1) {
     
        this.number = number;
        this.name = n1;
    }
public static void main(String arg[]) {
     
        String fname = "Student.obj"; //文件名
        Student s1 = new Student(1,"Wang");
        s1.save(fname);
        s1.display(fname);
}



void save(String fname) {
     
    try{
     
            FileOutputStream fout = new FileOutputStream(fname);
            ObjectOutputStream out = new ObjectOutputStream(fout);
            out.writeObject(this);               //对象序列化
            out.close();
    }
    catch (FileNotFoundException fe){
     }
    catch (IOException ioe){
     }
}
void display(String fname) {
     
     try{
     
            FileInputStream fin = new FileInputStream(fname);
            ObjectInputStream in = new ObjectInputStream(fin);
            Student u1 = (Student)in.readObject();  //对象反序列化
            System.out.println(u1.getClass().getName()+"  "+
                                 u1.getClass().getInterfaces()[0]);
            System.out.println("  "+u1.number+"  "+u1.name);
            in.close();
     }
     catch (FileNotFoundException fe){
     }
     catch (IOException ioe){
     }
     catch (ClassNotFoundException ioe) {
     }
}

(6)PipedInputStream(PipedReader)&PipedOutputStream(PipedWriter) :
管道输入流应连接到管道输出流; 管道输入流然后提供写入管道输出流的任何数据字节。 典型地,数据被从一个读PipedInputStream对象由一个线程并且数据被写入到对应的PipedOutputStream通过一些其它线程。 不建议尝试从单个线程使用这两个对象,因为它可能会使线程死锁。 管道输入流包含一个缓冲区,在读取操作中将读取操作与限制内的操作相分离。 的管道被认为是broken如果正在提供的数据字节到连接的管道输出流中的线程不再存活。
管道输出流可以连接到管道输入流以创建通信管道。 管道输出流是管道的发送端。 典型地,数据被写入到一个PipedOutputStream由一个线程对象和数据被从连接读取PipedInputStream通过一些其它线程。 不建议尝试从单个线程使用这两个对象,因为它可能会使线程死锁。 管被说成是broken如果从连接读取数据字节的螺纹管道输入流不再存活。
e.g.

import java.io.IOException;  
import java.io.PipedInputStream;  
import java.io.PipedOutputStream;  
public class PipedStream {
     
public static void main(String[] args) throws IOException {
       
      PipedInputStream in = new PipedInputStream();  
      PipedOutputStream out = new PipedOutputStream();  
      in.connect(out);  
      new Thread(new Input(in)).start();  
      new Thread(new Output(out)).start();  
    }  
} 

class Input implements Runnable{
        
    private PipedInputStream in;  
    public Input(PipedInputStream in) {
        
        this.in = in;  
    }  
    
    public void run() {
       
        byte []buf = new byte[1024];  
        int len;  
        try {
       
            len = in.read(buf);  
            String s = new String(buf,0,len);  
            System.out.println("in "+s);  
            in.close();  
        } catch (IOException e) {
       
              e.printStackTrace();  
        }   
    }  
  
      
} 
class Output implements Runnable{
       
private PipedOutputStream out;   
    public Output(PipedOutputStream out)   
    {
        
        this.out = out;  
    }  
    public void run() {
       
      try {
       
          out.write("hello".getBytes());  
      } 
      catch (IOException e) {
              
            e.printStackTrace();  
        }     
          
    }  
 
}

(7)PrintStream(PrintWriter) :
可以向该字符流中写入Java基本数据类型,用于包装输出字符流类对象
局限性:没有对应的输入流类用于恢复写入的Java基本类型数据

import java.io.*;
public class PrintWrit {
     
  public static void main(String[] args)throws Exception{
     
    PrintWriter out = new PrintWriter(new BufferedWriter(new 
                                    FileWriter("foo.txt")));
//等价于PrintWriter out = new PrintWriter(“foo.txt”); //JDK5引入,简化编码,仍然具有缓存功能
    out.println(“hello”); //写入字符串
    out.println(3); //写入整型
    out.close(); //关闭流,系统自动将缓冲区内容flush
  }  
}

(8)DataInputStream&DataOutputStream :
可从字节流中写入、读取Java基本数据类型,不依赖于机器的具体数据类型,方便存储和恢复数据

import java.io.*;
public class DataStream {
     
  public static void main(String[] args)throws Exception{
     
   try {
     
    DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new 
                                          FileOutputStream("test.txt")));
    dos.writeInt(3);//写入整型
        dos.writeDouble(3.14);//写入浮点型
    dos.writeUTF(“hello”);//写入字符串
    dos.close();

    DataInputStream dis = new DataInputStream(new BufferedInputStream(new 
                                          FileInputStream("test.txt")));
    System.out.println(dis.readInt()); //读取整型,输出3
    System.out.println(dis.readDouble()); //读取浮点型,输出3.14
    System.out.println(dis.readUTF()); //读取字符串,输出hello
    dis.close();
   } catch (FileNotFoundException e) {
     
         e.printStackTrace();
    }
  }
}

(9)StringBufferInputStream :已弃用
(10)BufferedInputStream(BufferedReader)&BufferedOutputStream(BufferedWriter) : 缓存作用,用于装配文件磁盘、网络设备、终端等读写开销大的节点流,提高读写性能

import java.io.*;
public class inDataSortMaxMinIn {
      
    public static void main(String args[]) {
     
     try{
     
        BufferedReader keyin = new BufferedReader(new 
                                     InputStreamReader(System.in)); 
        String c1;
        int i=0;
        int[] e = new int[10];   
        while(i<10){
     
           try{
     
               c1 = keyin.readLine();
               e[i] = Integer.parseInt(c1);
               i++;
            }  
            catch(NumberFormatException ee){
     
                   System.out.println("请输入正确的数字!");
            }
       }
    }
    catch(Exception e){
     
        System.out.println("系统有错误");
        }
    }
}

(11)LineNumberInputStream(LineNumberReader) :这个类是一个输入流过滤器,它提供了跟踪当前行号的附加功能。行是以回车符(’\r’)、换行符(’\n’)或紧跟换行符的回车字符结尾的字节序列。在所有三种情况下,行尾字符都作为一个换行符返回。行号从0开始,当读取返回换行符时,行号递增1。
(12)PushbackInputStream :回退流
(13)SequenceInputStream :A SequenceInputStream表示其他输入流的逻辑级联。 它从一个有序的输入流集合开始,从第一个读取到文件的结尾,然后从第二个文件读取,依此类推,直到最后一个输入流达到文件的结尾。

3.字节流与字符流的转化是怎么样的?Java对此提供了哪些支持?

输入字节流转为字符流需要用到inputstreamReader的构造方法:

InputStreamReader(InputStream in)

输出字符流转为字节流用到OutputStreamWriter或PrintWriter的构造方法:

OutputStreamWriter(OutputStream out)
PrintWriter(OutputStream out)

4.Java中的过滤流(流的装配)有什么作用?请举例说明常用的过滤流。

(1)BufferedInputStream&BufferedOutputStream, 缓存作用,用于装配文件磁盘、网络设备、终端等读写开销大的节点流,提高读写性能

import java.io.*;
public class inDataSortMaxMinIn {
      
    public static void main(String args[]) {
     
     try{
     
        BufferedReader keyin = new BufferedReader(new 
                                     InputStreamReader(System.in)); 
        String c1;
        int i=0;
        int[] e = new int[10];   
        while(i<10){
     
           try{
     
               c1 = keyin.readLine();
               e[i] = Integer.parseInt(c1);
               i++;
            }  
            catch(NumberFormatException ee){
     
                   System.out.println("请输入正确的数字!");
            }
       }
    }
    catch(Exception e){
     
        System.out.println("系统有错误");
 }}}

(2)DataInputStream和DataOutputStream
可从字节流中写入、读取Java基本数据类型,不依赖于机器的具体数据类型,方便存储和恢复数据

import java.io.*;
public class DataStream {
     
  public static void main(String[] args)throws Exception{
     
   try {
     
    DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new 
                                          FileOutputStream("test.txt")));
    dos.writeInt(3);//写入整型
        dos.writeDouble(3.14);//写入浮点型
    dos.writeUTF(“hello”);//写入字符串
    dos.close();

    DataInputStream dis = new DataInputStream(new BufferedInputStream(new 
                                          FileInputStream("test.txt")));
    System.out.println(dis.readInt()); //读取整型,输出3
    System.out.println(dis.readDouble()); //读取浮点型,输出3.14
    System.out.println(dis.readUTF()); //读取字符串,输出hello
    dis.close();
   } catch (FileNotFoundException e) {
     
         e.printStackTrace();
    }
  }
}

(3)PrintWriter
可以向该字符流中写入Java基本数据类型,用于包装输出字符流类对象
局限性:没有对应的输入流类用于恢复写入的Java基本类型数据

import java.io.*;
public class PrintWrit {
     
  public static void main(String[] args)throws Exception{
     
    PrintWriter out = new PrintWriter(new BufferedWriter(new 
                                    FileWriter("foo.txt")));
//等价于PrintWriter out = new PrintWriter(“foo.txt”); //JDK5引入,简化编码,仍然具有缓存功能
    out.println(“hello”); //写入字符串
    out.println(3); //写入整型
    out.close(); //关闭流,系统自动将缓冲区内容flush
  }  
}

5.什么是对象的序列化和反序列化?Java对此提供了哪些支持?

序列化&反序列化 :将实现了Seriallizable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象。

使用ObjectInputStream类和ObjectOutputStream类
e.g.

import java.io.*;
 public class Student implements Serializable {
      //序列化
    int number=1;
    String name;
    Student(int number,String n1) {
     
        this.number = number;
        this.name = n1;
    }
public static void main(String arg[]) {
     
        String fname = "Student.obj"; //文件名
        Student s1 = new Student(1,"Wang");
        s1.save(fname);
        s1.display(fname);
}



void save(String fname) {
     
    try{
     
            FileOutputStream fout = new FileOutputStream(fname);
            ObjectOutputStream out = new ObjectOutputStream(fout);
            out.writeObject(this);               //对象序列化
            out.close();
    }
    catch (FileNotFoundException fe){
     }
    catch (IOException ioe){
     }
}
void display(String fname) {
     
     try{
     
            FileInputStream fin = new FileInputStream(fname);
            ObjectInputStream in = new ObjectInputStream(fin);
            Student u1 = (Student)in.readObject();  //对象反序列化
            System.out.println(u1.getClass().getName()+"  "+
                                 u1.getClass().getInterfaces()[0]);
            System.out.println("  "+u1.number+"  "+u1.name);
            in.close();
     }
     catch (FileNotFoundException fe){
     }
     catch (IOException ioe){
     }
     catch (ClassNotFoundException ioe) {
     }
}

6.Java的File类表示什么?有什么作用?

File类不仅指系统中的文件,也指目录,因为目录也是特殊的文件。它的主要方法类型和说明见表。

类型 名称 说明
构造方法 public File(String pathname) 根据字符串路径建立文件对象
public File(File parent,String child) 根据父路径对象和子路径字符串建立文件对象
public File(String parent parent,String child) 根据父路径字符串和子路径字符串建立文件对象
文件名的处理 String getName(); 得到一个文件的名称(不包括路径)
String getPath(); 得到一个文件的路径名
String getAbsolutePath(); 得到一个文件的绝对路径名
String getParent(); 得到一个文件的上一级目录名
String renameTo(File newName); 将当前文件更名为参数File所代表路径下的文件
文件属性测试 boolean exists() 测试当前File对象所代表的文件是否存在
boolean canWrite() 测试当前File对象所代表的文件是否可写
boolean canRead() 测试当前File对象所代表的文件是否可读
boolean isFile() 测试当前File对象是否是文件
boolean isDirectory() 测试当前File对象是否是目录
文件信息和文件删除 long lastModified() 得到文件最近一次修改时间
long length() 得到文件的长度,以字节为单位
boolean delete() 删除当前文件
目录操作 boolean mkdir() 生成当前File对象所代表的目录
String list() 列出当前目录下的文件

7.Java对文件的读写分别提供了哪些支持?

FileInputStream 以字节流的形式顺序读文件
FileReader以字符流的形式顺序读文件
FileOutputStream 以字节流的形式顺序写文件
FileWriter 以字符流的形式顺序写文件
RandomAccessFile 提供对文件的随机访问支持

你可能感兴趣的:(java,java)