OutputStream
OutputStream:字节输出流的根类(基类,顶级父类),定义了所有字节输出流应该具备的方法
FileOutputStream:文件输出流是用于将数据写入文件的输出流
public abstract void write(int b)写入一个字节
public void writer(byte[] b) 写出 一个字节数组的字节
public void close() 关闭io资源
fos.write(0b01100001);//当前输入的是一个a的二进制字节码
fos.write(97);
fos.write('a');
输出流的源代码实现:如果输出时没有该文件,则会先创建该文件,再输出数据
默认的写出是覆盖掉了文件以前的内容,如果想每次运行程序写出数据不覆盖之前的内容,使用特定的构造方法
public FileOutputStream(String name,boolean append) append参数:是否追加数据
在FileOutputStream的构造方法当中,指定的io资源可以是文件对象,也可以是文件路径,其本质是相同的。
一般情况下直接使用给予文件路径的方式创建IO流对象,因为源代码中会自动帮助我们创建File对象。
InputStream
InputStream:字节输入流的根类(基类,顶级父类),定义了所有字节输入流应该具备的方法
FileInputStream:文件输入流是用于从文件当中读取数据的输入流
public static void main(String[] args) throws Exception {
//读取当前项目下的StringDemo.java文件
FileReader fr = new FileReader("StringDemo.java")
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=fr.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
//释放资源
fr.close();
public int read() 一次读取一个字节,返回的就是这个字节本身,读取到文件末尾返回-1
package test1;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
FileOutputStream out = new FileOutputStream("b.txt");
int b = 0;
while((b=in.read())!=-1){
out.write(b);
}
out.close();
in.close();
}
}
public int read(byte[] b):读取一个字节数组,返回是本次读取的字节个数,参数用于每次存储字节数据的数组,读取到文件末尾返回-1
package test1;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileCopy2 {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("a.txt");
out = new FileOutputStream("c.txt");
byte[] b = new byte[10];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
}catch (IOException e){
}finally {
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
}
}
- 高效流 - 高级流
- 原理:缓存区 - 临时存放多个数据,一次性调用底层的资源,减少调用的次数,从而提升程序运行的效率
- 所以在高级流的低层需要一个低级流作为支撑
- 高效字节流的api:
- BufferedInputStream/BufferedOutputStream
- 高效流和普通流基本一样,高效流使用普通流作为构造函数的参数,在普通流的基础上增加了缓存区
- 高效write写出的时候,写出的位置是在缓存区,并不是目标资源
- 需要通过flush()方法将缓存区中的内容写到目标资源中 - 目的是提高效率
- 方法:
- void flush() - 刷新缓存区
- void close() - 关闭流,关闭前调用flush()方法
读取文本打印到控制台
package test1;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.jar.JarOutputStream;
/**
*读取文本打印到控制台
*/
public class FileInputStreamTest2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("a.txt");
ArrayList<Byte> list = new ArrayList<>();
byte b[] = new byte[50];
int len=0;
while ((len=fis.read(b))!=-1){
//准确的获取每一个元素
for (int i = 0; i < len; i++) {
list.add(b[i]);
}
//System.out.print(new String(b,0,len));
}
byte[] bytes = listToArray(list);
System.out.println(new String(bytes,0,bytes.length));
fis.close();
}
//定义一个方法,传入一个ArrayList集合,集合的泛型是数组,将集合中所有数组拼接在一起,返回一个大数组
public static byte[] listToArray(ArrayList<Byte> list){
//计算list中每个元素的长度,求总长度len
int len = list.size();
//根据总长创建一个大数组
byte[] bytes = new byte[len];
//嵌套遍历list元素的每个元素,有序取出有序放去大数组
for (int i = 0; i < list.size(); i++) {
bytes[i] = list.get(i);
}
//返回大数组
return bytes;
}
}