IO流分为很多种,其中根据操作数据的不同,可以分为字节流和字符流;字节流又可细化为输入字节流InputStream和输出字节流OutputStream;字符流分为输入字符流Reader和输出字符流Writer。
在写入文件时,默认先将文件清空,再向其中写入新的数据,当append为true时,追加数据。
字节流
计算中的数据信息都是以二进制的形式存在的,针对字节的传输提供了字节流。字节输入流和字节输出流是所有输入输出流的顶级父类,下面所有的都是继承自二者之一,就像是连接在源设备到目标程序之间连通的一条管道,通过这条管道进行字节的传输操作。
输入字节流的常用方法
方法 | 功能描述 |
---|---|
int read() | 从输入流读取8个字节的数据,将其转化为整数并返回(0-255间的整数) |
int read(byte[] b) | 输入流读取若干字节保存到指定数组b中,返回的整数表示读取字节数 |
int read(byte b[], int off, int len) | 输入流读取若干字节保存到指定数组b中,off指定保存的起始下标,len表示读取的字节数目 |
void close() | 关闭输入流并释放所占用的系统资源 |
输出字节流的常用方法
方法 | 功能描述 |
---|---|
int write(int b) | 向输出流写入一个字节 |
int write(byte[] b) | 将指定参数数组b中的数据全部写到输出流 |
int write(byte b[], int off, int len) | 将数组b中从off指定保存的起始下标的len个字节写入到输出流 |
void close() | 关闭输入流并释放所占用的系统资源 |
void flush() | 刷新输出流并强制写出所有缓冲的输出字节 |
字节流读写文件的操作
//字节流读写文件的操作
public static void main(String[] args) throws IOException {
// 输出流测试
/**
* FileOutputStream 如果是已存在文件会将原本内容清除,然后写入新的内容
* 如果想数据中追加内容使用FileOutputStream("E://Test2.txt",true)
* */
FileOutputStream outputStream = new FileOutputStream("E://Test.txt");
String str = "Donbt";
byte[] data = str.getBytes();
for (int i = 0; i < data.length; i++) {
outputStream.write(data[i]);
}
outputStream.close();
FileOutputStream outputStream1 = new FileOutputStream("E://Test2.txt");
String str1 = "Test I/O";
byte[] data1 = str.getBytes();
outputStream1.write(data1,0,data1.length);
System.out.println("输出完毕");
// 输入流测试
FileInputStream fileInputStream = new FileInputStream("E://Test.txt");
int b=0;
while (true)
{
b = fileInputStream.read();
if (b == -1)
{
break;
}
System.out.println(b);//得到的所对应的十进制数--ASCII
// 关闭 一般写在finally{}中
outputStream.close();
outputStream1.close();
fileInputStream.close();
}
为了提高效率,这样一个字节一个字节的去读写,需要频繁的对文件进行操作,效率很低,这里就需要将文件中的数据分批进行处理,建立一个临时缓冲区,可以定义一个字节数组作为一个缓冲区,然后将数组中的数据一次性写入,而不是一个字节一个字节的进行操作。
public static void main(String[] args) throws IOException {
FileInputStream fi = new FileInputStream("E://Test.txt");
FileOutputStream fo = new FileOutputStream("E://out.txt");
// 作为缓冲区的数组
byte[] data = new byte[1024];
// len 记录读取读入字节数
int len;
long be= System.currentTimeMillis();
while ((len = fi.read(data)) != -1)
{
fo.write(data,0,len);
}
long en= System.currentTimeMillis();
System.out.println("success:"+(en-be)+"ms");
}
字节缓冲流
/**
* 字节缓冲流---通过装饰设计模式实现
* 流的内部定义好了大小为8192的字节数组
* BufferedInputStream 接收的是一个InputStream类型的对象
* */
public static void main(String[] args) throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E://Test.txt"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("E://out.txt"));
int len;
//(len = bufferedInputStream.read()) != -1 是否读到文件末尾
while ((len = bufferedInputStream.read()) != -1)
{
bufferedOutputStream.write(len);
}
System.out.println("success");
//关闭流
try {
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
字符流
字符流也存在两个顶级父类Reader 和Writer。
字符输入流read()方法获得的值是int类型,想获得字符就需要进行强转。
/**
* 字符流也有自己带缓冲区的包装流BufferedReader、BufferedWriter。
* readLine 一次读取一行文本。
* 因字符先被写入缓冲区,当缓冲区被写满或者被关闭时才会将缓冲区中的文件写入目标文件,
* 一定要调用close方法,否则容易出现文件内容丢失。
* */
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("E://Test.txt");
// 缓冲对象
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("E://Test3.txt");
BufferedWriter bw = new BufferedWriter(fw);
String Str;
// br.readLine()每次读取一行文本
while ((Str = br.readLine())!= null)
{
// 写入
bw.write(Str);
// 写入换行符
bw.newLine();
}
br.close();
bw.close();
前面提到了字节流和字符流,二者之间有时也需转换,jdk中提供了两个类用来将字节流转换为字符流。InputStreamReader和OutputStreamWriter,转换流也是一种包装流
FileInputStream fs = new FileInputStream("E://Test.txt");//字节流
InputStreamReader streamReader = new InputStreamReader(fs);//字节流转换为字符流
BufferedReader br = new BufferedReader(streamReader);//包装字符流对象
String str2;
while ((str2 = br.readLine()) != null)
{
System.out.println(str2);
}
br.close();