第十四章小结—IO输入输出流
1. Java中流的分类有哪些?
流从流动方向: 一般分为 输入流(InputStream) 和 输出流(OutputStream) 两类。程序可以用输出流向文件写数据,用输入流从文件中读数据。而针对屏幕只有输出流。
从读取类型上分: 一般分为字节流和字符流。
字节流: 是从InputStream 和 OutputStream 派生出来的一系列类,它以字节(byte)为基本处理单位。它们的继承关系如下(缩进的层次表示继承关系)
InputStream
OutputStream
字符流:是从Reader 和 Writer 派生出的一系列类,它以16位的Unicode 码 表示的字符位基本处理单位。它们的继承关系如下(缩进的层次表示继承关系)
Reader
Writer
流从发生的源头: 可以分为节点流 和 过滤流。用于直接操作目标设备对应的流叫节点流(文件流,字节数组流,标准输入/输出流等)。程序可以通过过滤流(继承带有关键字Filter 的流),以更加灵活方便地读写各种类型的数据。
2.字节流InputStream和OutputStream的子类分别有哪些?请举例说明其使用场景。与其对应的字符流分别有哪些?
字节流: 是从InputStream 和 OutputStream 派生出来的一系列类,它以字节(byte)为基本处理单位。它们的继承关系如下(缩进的层次表示继承关系)
InputStream
FileInputStream 文件流
PipedInputStream 管道输入流,读取管道内容。多和PipedOutputStream一起用于多线程通信
ObjectInputStream用来恢复被序列化的对象
ByteArrayInputStream包含一个内存缓冲区,字节从中取出。
SequenceInputStream 是多种输入流的逻辑串联,从第一个输入流读取,直到最后一个输入流
FilterInputStream 过滤流,在读写数据的同时还可以对数据进行特殊处理
OutputStream
FileOutputStream 文件流
PipedOutputStream 管道流
ObjectOutputStream将对象序列化后写入指定地方
ByteArrayOutputStream在字节数组和流之间搭建桥梁
SequenceOutputStream 是多种输入流的逻辑串联
FilterInputStream 过滤流,在读写数据的同时还可以对数据进行特殊处理
字符流:是从Reader 和 Writer 派生出的一系列类,它以16位的Unicode 码 表示的字符位基本处理单位。它们的继承关系如下(缩进的层次表示继承关系)
Reader
Writer
3.字节流与字符流的转化是怎样的?Java对此提供了哪些支持?
输入字节流转化为字符流需要用到InputStreamReader的构造方法:
InputStreamReader(InputStream in)
例如:
InputStreamReader ins = new InputStreamReader(FileInputStream("c:\\text.txt"));
//之后通过ins的方法就可以从字符的角度来读取文件text.txt.
InputStreamReader ins = new InputStreamReader(System.in);// 从键盘读取数据
输出字符流转化为字节流 用到OutputStreamWriter 或 PrintWriter 的构造方法。
OutputStreamWriter(OutputStream out)
PrintWriter(OutputStream out)
例如:
OutputStreamWriter outs = new OutputStreamWriter(new FileOutputStream("c:\\text.txt"));
// 之后通过outs 就可以直接输出字符到text.txt文件中。
4.Java中的过滤流(流的装配)有什么作用?请举例说明常用的过滤流。
流的装配
DataInputStream di = new DataInputStream(new BufferedInputStream(new FileInputSTream(f))); //f 为File的实例。
之后可以利用DataOutStream 对象方法想文件中写内容。党内容写完后,可调用其flush 方法,将多次写入的数据一次性输出到节点流FileOutStream 上;如果用PrintStream 取代现在DataOutputStream 的位置,则当调用其println 方法或其写入的字符中含有换行时,会自动调用BufferedOutputStream的flush 将缓冲区的内容写入到字节流中。
过滤流: BufferedInputStream 和 BufferedOutputStream,缓存作用,用于装配文件磁盘,网络设备,终端等读写开销大的节点流,提高读写性能。
例如:
过滤流BufferedReader的使用:用于缓存字符流,可以一行一行的读
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("系统有错误");
}}}
过滤流: 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();
}
}
}
5.什么是对象的序列化和反序列化?Java对此提供了哪些支持?
对象序列化(串行化) ,将实现了Seriallizable借口的对象装换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象,后者又称为反序列化。
对象序列化的目的: 便于介质存储和网络传输
使用类: ObjectInputStream 和 ObjectOutputStream
分别实现了接口ObjectOutput 和 ObjectInput,将数据流功能扩展到可以读写对象,前者用writeObject()方法可以直接将对象保存到输出流中,而后者用readObject()方法可以直接从输入流中读取一个对象。
import java.io.*;
public class Student implements Serializable //序列化
{
int number=1;
String name;
Student(int number,String n1)
{ this.number = number;
this.name = n1;
}
Student()
{ this(0,""); }
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) {}
}
public static void main(String arg[])
{
String fname = "Student.obj"; //文件名
Student s1 = new Student(1,"Wang");
s1.save(fname);
s1.display(fname);
}
}
/** 本例声明Student 为串行化的类,该类的save方法创建对象输出流out,并向文件直接写入当前对象。在display 方法中,创建对象输入流in,从文件中直接读取一个对象,获得该对象的类名,接口名等属性,并显示其中的域变量值。*/
6.Java的File类表示什么?有什么作用?
file类不仅值系统中的文件,也值目录,因为目录也是特殊的文件。
文件相关类或接口
名称 | 类型 | 说明 |
---|---|---|
File | 类 | 文件(或目录)路径名字的抽象表示 |
FileDescriptor | 类 | 代表一个打开文件的文件描述 |
FileFilter & FilenameFilter | 接口 | 列出满足条件的文件,用于:File.list(FilenameFilter fnf) ;File.listFiles(FileFilter ff) ; FileDialog.setFilenameFilter(FilenameFilter fnf);FileDialog是java.awt包中的类。 |
FileInputStream | 类 | 以字节流的形式顺序读文件 |
FileReader | 类 | 以字符流的形式顺序读文件 |
FileOutputStream | 类 | 以字节流的形式顺序写文件 |
FileWriter | 类 | 以字符流的形式顺序写文件 |
TRandomAccessFile | 类 | 提供醉文件的随机访问支持 |
File类相关方法:
7.Java对文件的读写分别提供了哪些支持?
以字节流的形式顺序读写文件 FileInputStream 和 FileOutputStream
读入
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 (IOException ioe)
{ System.out.println(ioe);}
catch (Exception e)
{ System.out.println(e);}
}
}
写文件
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 (IOException ioe)
{ System.out.println(ioe);}
catch (Exception e)
{ System.out.println(e);}
}
}
以字符流的形式顺序的读文件:FileReader 和FileWriter
读文件:
import java.io.*;
public class OpenFile
{
public static void main(String args[]) throws IOException
{
try
{ //创建文件输入流对象
FileReader rf = new FileReader("OpenFile.java");
char[] a = new char[50];
rf.read(a); // 读取数组中的内容
for (char c : a)
System.out.print(c); // 一个一个打印字符
rf.close(); //关闭输入流
}
catch (IOException ioe)
{ System.out.println(ioe);}
catch (Exception e)
{ System.out.println(e);}
}
}
写文件
import java.io.*;
public class Write1
{
public static void main(String args[])
{
try
{
FileWriter wf = new FileWriter("Write1.txt");
//创建文件输出流对象
wf.write("This\n is\n an\n example\n");
wf.flush();
wf.close(); //关闭输出流
System.out.println("Save to Write1.txt!");
}
catch (IOException ioe)
{ System.out.println(ioe);}
catch (Exception e)
{ System.out.println(e);}
}
}