概述
InputStream和OutputStream这两个类是字节流中所有类的父类,这两个类都是抽象类,不能直接创建对象。由这两者派生的子类可以选择性地重写两个父类的成员方法来实现更多功能,但必须实现父类的read/writer方法。
Java的标准输入/输出(System.in/System.out)
- Java的标准输入输出流就是System.in/out,两者都被定义成了常量类型,System.in通常对应于键盘输入,System.out通常对应于显示器输出。
- 示例:
public class TestSystem {
public static void main(String[] args) {
//构造从键盘输入的实例
Scanner scanner = new Scanner(System.in);
//从键盘获取数据
String string = scanner.next();
//从控制台输出数据
System.out.println("从键盘输入的数据为: " + string);
}
}
文件输入/输出流
- FileInputStream类创建一个能从文件读取字节的字节输入流,常用的有两个构造方法:
1.public FileInputStream(File file),该参数为File类型的文件对象
2.public FileInputStream(String name),该参数为文件的完全路径名 - FileOutputStream类创建一个可以向文件写入字节的OutputStream,常用的构造方法和InputStream类似:
1.public FileOutputStream(String name)
2.public FileOutputStream(File file) - 示例:
public class TestFileStream {
public static void main(String[] args){
FileInputStream input = null;
FileOutputStream output = null;
try {
//用文件绝对路径构造输入输出流
input = new FileInputStream("C:\\Users\\xxx\\Desktop/0.jpg");
output = new FileOutputStream("C:\\Users\\xxx\\Desktop/5.jpg");
//文件读写
int tmp;
//每次通过输入流读取文件中的一个字节
while ((tmp = input.read()) != -1){
//将读取到的一个字节通过输出流写到文件中
output.write(tmp);
}
}catch (IOException e){
e.printStackTrace();
}finally {
//退出输入输出流
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//构造两个文件对象
File infile = new File("C:\\Users\\xxx\\Desktop/1.jpg");
File outfile = new File("C:\\Users\\xxx\\Desktop/6.jpg");
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
//用文件对象构造输入输出流
fileInputStream = new FileInputStream(infile);
fileOutputStream = new FileOutputStream(outfile);
//构造一个大小为infile文件大小的字节数组
byte[] a = new byte[(int)infile.length()];
//将文件对象读取到字节数组中
fileInputStream.read(a);
//将字节数组中的数据通过输出流写到文件中
fileOutputStream.write(a);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
//退出输入输出流
fileInputStream.close();
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
数据字节输入/输出流
- 数据输入流允许应用程序以与机器无关的方式从基础输入流中读取原始Java数据类型。应用程序使用数据输出流来写入数据,以后可以由数据输入流读取。构造函数:public DataInputStream(InputStream in),创建一个使用指定的基础InputStream的DataInputStream,
- 数据输出流允许应用程序以可移植的方式将原始Java数据类型写入输出流。然后,应用程序可以使用数据输入流来读回数据。构造函数:public DataOutputStream(OutputStream out),创建一个新的数据输出流,以将数据写入指定的基础输出流。
- 示例:
使用基本与其他输入输出流相同,示例中代码有不明之处可参考文件输入输出流示例
public class TestDataStream {
public static void main(String[] args) {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\xxx\\Desktop/0.jpg");
dataInputStream = new DataInputStream(fileInputStream);
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\xxx\\Desktop/0.jpg");
dataOutputStream = new DataOutputStream(fileOutputStream);
//文件读写
int tmp;
//每次通过输入流读取文件中的一个字节
while ((tmp = dataInputStream.read()) != -1){
//将读取到的一个字节通过输出流写到文件中
dataOutputStream.write(tmp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
dataInputStream.close();
dataOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
对象输入/输出流
- 对象的寿命通常随着生成该对象的程序的终止而终止,但是有时候需要将对象的状态保存下来,在需要时将其恢复。ObjectInputStream对象输入流配合ObjectOutputStream对象输出流就可以实现对象的序列化。
- 在Java中,接口Serializeable用来作为实现对象串行化的工具,只有实现了Serializable类的对象才可以被序列化。
- 序列化就是可以将对象写入到磁盘中
- 示例:
class Person implements Serializable{
private String name;
private int age;
public Person(String name, int age) {
System.out.println("实例化Person对象");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class TestSerializable {
public static void main(String[] args) {
//实例化一个可以序列化的Person对象
Person person = new Person("张三",20);
ObjectOutputStream oops = null;
ObjectInputStream ois = null;
try{
//构造对象输入输出流
oops = new ObjectOutputStream(new FileOutputStream("E:/Java/a.txt"));
ois = new ObjectInputStream(new FileInputStream("E:/Java/a.txt"));
//将Person对象写到文件中
oops.writeObject(person);
//将文件中的对象读到对象中
Person person1 = (Person)ois.readObject();
//从控制台输出
System.out.println(person1.getName() + person1.getAge());
}catch(IOException | ClassNotFoundException e){
e.printStackTrace();
}finally {
try {
//退出流
oops.close();
ois.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
缓冲字节流
- 缓冲流是一种字节流,通过把内存缓冲区连到输入/输出流而扩展一个过滤流 。该缓冲区允许Java对多个字节同时进行输入/输出操作,因此可以减少访问硬盘次数,提高程序的性能和效率。缓冲机制是一种较为普遍的优化性能方式,对于流也一样。
- BufferedInputStream缓冲输入流。Java的BufferedInputStream类允许把任何InputStream类封装成缓冲流。BufferedInputStream有如下两个构造方法:
1.public BufferedInputStream(InputStream in),创建默认缓冲大小(默认大小为8192字节)的缓冲流。
2.public BufferedInputStream(InputStream in, int size),创建缓冲大小为size的缓冲流。 - BufferedOutputStream缓冲输出流。和其他OutputStream一样,此处用flush()方法确保缓冲区字节数据被写入实际的输出设备外,还使所有缓冲的输出字节被写出到基础输出流中。BufferedOutputStream有如下两个构造方法:
1.public BufferedOutputStream(OutputStream out),创建一个新的大小默认(8192)的缓冲输出流,以将数据写到指定的基础输出流。
2.public BufferedOutputStream(OutputStream out, int size),创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输入流。 - 示例:
public class TestBufferedStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("E:/Java/a.txt");;
BufferedInputStream bufferedInputStream = new BufferedInputStream(fis,256);
byte[] arr = new byte[256];
bufferedInputStream.read(arr);
System.out.println(Arrays.toString(arr));
}
}