目录
InputStream
是Java所有字节输入流的父类,OutputStream
是Java所有字节输出流类的父类。它们都是一个抽象类,因此继承它们的子类要重新定义父类中的抽象方法。
字节输入流
InputStream
类及其子类的对象表示字节输入流
ByteArrayInputStream
类: 将字节数组转换为字节输入流,从中读取字节
FileInputStream
类: 从文件中读取数据
PipedInputStream
类: 连接到一个PipedOutputStream
(管道输出流)
SequenceInputStream
类: 将多个字节输入流串联成一个字节输入流
ObjectInputStream
类: 将对象反序列化
使用InputStream
类的方法可以从流中读取一个或一批字节
方法名及返回值类型 | 说明 |
---|---|
int read() | 从输入流中读取一个8位的字节,并把它转换为0-255的整数,最后返回整数。如果返回-1,则表示到了输入流的末尾 |
int read(byte[] b) | 从输入流中读取若干字节,并把它们保存到参数b指定的字节数组中。该方法返回读取的字节数。如果返回-1,表示已经到了输入流的末尾 |
int read(byte[] b, int off, int len) | 从输入流中读取若干字节,并把它们保存到参数b指定的字节数组中。off指定在字节数组中开始保存数据的其实下标;len指定读取的字节数。该方法返回实际读取的字节数。返回-1时,表示到了输入流的末尾 |
void close() | 关闭输入流。读取操作完成后,应该关闭输入流,系统将会释放这个输入流相关的资源。注意: InputStream类本身的close()方法不执行任何操作,但是它的子类重写了close()方法 |
int available() | 返回可以从输入流中读取的字节数 |
long skip(long n) | 从输入流中跳过参数n指定数目的字节。该方法返回跳过的字节数 |
void mark(int readLimit) | 在输入流的当前位置开始设置标记,参数readLimit则制定了最多被设置标记的字节数 |
boolean markSupported() | 判断当前输入流是否允许设置标记,是返回true,否则返回false |
void reset() | 将输入流的指针返回到设置标记的起始处 |
注意: 在使用mark()和reset()方法之前,需要判断该文件系统是否支持这两个方法,以避免对程序造成影响。
字节输出流
OutputStream
类及其子类对象的表示一个字节输出流
ByteArrayOutputStream
类: 向内存缓冲区的字节数组中写数据
FileOutputStream
类: 向文件中写数据
PipedOutputStream
类: 连接到一个PipedInputStream
(管道输入流)
ObjectOutputStream
类: 将对象序列化
利用OutputStream
类的方法可以从流中写入一个或者一批字节
方法名及返回值类型 | 说明 |
---|---|
void write(int b) | 向输出流写入一个字节。这里的参数是int类型,但是它允许使用表达式,而不用强制转换成byte类型。 |
void write(byte[] b) | 把参数b指定的自己数组中的所有字节写道输出流中 |
void write(byte[] b, int off, int len) | 把参数b指定的字节数组中的若干字节写到输出流中。其中,off指定字节数组的起始下标,len表示元素个数 |
void close() | 关闭输出流。写操作完成后,应该关闭输出流。洗头膏将会释放与这个输出流相关的资源。 |
void flush() | 为了提高效率,向输出流中写入数据时,数据一般会先保存到内存缓冲区中,只有当缓冲区中的数据达到一定程度时,缓冲区中的数据才会被写入输出流中。使用flush()方法则可以强制将缓冲区中的数据写入输出流,并清空缓冲区 |
字节数组输入流
ByteArrayInputStream
类可以从内存的字节数组中读取数据,该类有两种构造方法重载形式。
ByteArrayInputStream(byte[] buf)
: 创建一个字节数组输入流,字节数组类型的数据源由参数buf指定
ByteArrayInputStream(byte[] buf, int offset, int length)
: 创建一个字节数组输入流,其中,参数buf指定字节数组类型的数据源,offset指定在数组中开始读取数据的起始下标位置,length指定读取的元素个数
public class test {
public static void main(String[] args) {
byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 };
// 创建数组
ByteArrayInputStream bais =
new ByteArrayInputStream(b, 0, 6);
// 创建字节数组输入流
int i = bais.read();
// 从输入流中读取下一个字节,并转换成int型数据
while (i != -1) {
// 如果不返回-1,则表示没有到输入流的末尾
System.out.println("原值=" + (byte) i +
"\t\t\t转换为int类型=" + i);
i = bais.read(); // 读取下一个
}
}
}
//输出:
原值=1 转换为int类型=1
原值=-1 转换为int类型=255
原值=25 转换为int类型=25
原值=-22 转换为int类型=234
原值=-5 转换为int类型=251
原值=23 转换为int类型=23
字节数组输出流
ByteArrayOutputStream
类可以向内存的字节数组中写入数据,该类的构造方法有两种重载
ByteArrayOutputStream
(): 创建一个字节数组输出流,输出流缓冲区的初始容量大小为32字节
ByteArrayOutputStream
(int size
): 创建一个字节数组输出流,输出缓冲区的初始容量大小由参数size指定
ByteArrayOutputStream
类中除了有前面介绍的字节输出流中常用的方法以外,还有两个方法
int size
(): 返回缓冲区中的当前字节数
byte[] toByteArray
(): 以字节数组的形式返回输出流中的当前内容
public class Test {
public static void main(String[] args) {
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 };
// 创建数组
baos.write(b, 0, 6);
// 将字节数组b中的前4个字节元素写到输出流中
System.out.println("数组中一共包含:" +
baos.size() + "字节");
// 输出缓冲区中的字节数
byte[] newByteArray = baos.toByteArray();
// 将输出流中的当前内容转换成字节数组
System.out.println(Arrays.toString(newByteArray));
// 输出数组中的内容
}
}
//输出为:
数组中一共包含:6字节
[1, -1, 25, -22, -5, 23]
文件输入流
FileInputStream
是Java流中比较常用的一种,它表示从文件系统的某个文件中获取输入字节。通过使用FileInputStream
可以访问文件中的一个字节、一批字节或整个字节。
在创建FileInputStream
类的对象时,如果找不到指定的文件将抛出FileNotFoundException
异常,该异常必须捕获或声明抛出。
FileInputStream
常用的构造方法主要有如下两种重载形式
FileInputStream(File file)
: 通过打开一个到实际文件的链接来创建一个FileInputStream
,该文件通过文件系统中的File对象file指定
FileInputStream(String name)
: 通过打开一个到实际文件的链接来创建一个FileInputStream
,该文件通过文件系统的路径名name指定
public class Test {
public static void main(String[] args) {
try {
FileInputStream f1 = new FileInputStream(
new File("D:\\test.txt"));
//以File对象作为参数创建FileInputStream对象
FileInputStream f2 =
new FileInputStream("D:\\test01.txt");
//以File字符串值作为参数创建FileInputStream对象
} catch (FileNotFoundException e) {
System.out.println("指定的文件找不到!");
}
}
}
有一个D:\JAVA study\A2.java 文件,下面使用FileInputStream
类读取并输出该文件的内容。
public class Test3 {
public static void main(String[] args) {
File f = new File("D:\\JAVA study\\A2.java");
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
//因为File没有读写的能力,所以需要有个InputStream
byte[] bytes = new byte[1024];
//定义一个字节数组
int n = 0;
//得到实际读取到的字节数
System.out.println("D:\\JAVA study\\
A2.java文件内容如下:");
while((n= fis.read(bytes)) != -1) {
//循环读取
String s = new String(bytes,0,n);
//将数组中从下标0到n的内容给s
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 输出为:
D:\JAVA study\A2.java文件内容如下:
public class A2{
public static void main(String[] args){
int num =3;
int num1=34;
System.out.println(num>>2);//除法
System.out.println(num<<2);//乘法
System.out.println(num&3);
System.out.println(num&1);//获取二进制最低位数字 判断奇数偶数
System.out.println("是奇数吗?"+((num&1)==1));
System.out.println((num1<50)&(num<37));
System.out.println((num1>50)&(num1++>37));
System.out.println(num1);
System.out.println(num|5);
}
}
注意: FileInputStream
类重写了父类InputStream
中的read()方法、skip()方法、available()方法和close()方法,不支持mark()方法和reset()方法
文件输出流
FileOutputStream
类继承自OutputStream
类,重写和实现了父类中的所有方法
FileOutputStream
类的对象表示一个文件字节输出流,可以向流中写入一个字节或一批字节。在创建FileOutputStream
类的对象时,如果指定的文件不存在,则创建于一个新文件;如果文件已存在,则清除源文件的内容重新写入。
FileOutputStream
类的构造方法有4种重载形式。
FileOutputStream(File file)
: 创建一个文件输出流,参数file指定目标文件
FileOutputStream(File file, boolean append)
: 创建一个文件输出流,参数file指定目标文件,append指定是否将数据添加到目标文件的内容末尾,如果为true,则在末尾添加;如果为false,则覆盖原有内容;其默认值为 false
FileOutputStream(String name)
: 创建一个文件输出流,参数name指定目标文件的文件路径信息
FileOutputStream(String name, boolean append)
: 创建一个文件输出流,参数name 和 append的含义同上
对文件输出流有如下四点说明:
1.在FileOutputStream
类的构造方法中指定目标文件时,目标文件可以不存在。
2.目标文件的名称可以时任意的,例如 D:\\abc.de 和 D:\\abc.de.fg 等都可以,可以使用记事本等工具打开并浏览这些文件中的内容
3.目标文件所在目录必须存在,否则会抛出java.io.FileNotFoundException异常
4.目标文件的名称不能是已存在的目录。例如D盘下已存在Java文件夹,那么就不能使用Java作为文件名,即不能使用D:\\Java ,否则抛出java.io.FileNotFoundException异常
public class Test4 {
public static void main(String[] args) {
FileInputStream f1 = null;
//声明FileInputStream对象f1
FileOutputStream f2 = null;
//声明FileOutputStream对象f2
try {
File srcFile = new File("D:\\JAVA
study\\A3.java");
f1 = new FileInputStream(srcFile);
//实例化FileInputStream对象
File targetFile = new File("D:\\JAVA
study\\A3.txt");
//创建目标文件对象,该文件不存在
f2 = new FileOutputStream(targetFile);
//实例化FileOutputStream对象
byte[] bytes = new byte[1024];
//每次读取1024个字节
int i = f1.read(bytes);
while(i!=-1) {
f2.write(bytes,0,i);
//向D:\\JAVA study\\A3.txt文件中写入内容
i = f1.read(bytes);
}
System.out.println("写入结束!");
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
f1.close();
//关闭FileInputStream对象
f2.close();
//关闭FileOutputStream对象
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
将D:\JAVA study\A3.java 文件中的内容通过文件输入/输出流写入到了D:\JAVA study\A3.txt 文件中。由于A3.txt文件并不存在,所以在执行程序时将新建此文件,并写入相应内容
技巧: 在创建 FileOutputStream
对象时,如果将append参数设置为true,则可以在目标文件的内容末尾添加数据,此时目标文件仍然可以暂不存在