IO流的概念
IO流也称为输入输出流,就是用来读写数据的
IO流的分类
FileInputStream(文件字节输入流)
作用
以内存在基准,把磁盘文件中的数据以字节的形式读取到内存中去
构造器
public FileInputStream(File file):创建字节输入流管道与源文件对象接通
public FileInputStream(String pathname):创建字节输入流管道与源文件路径接通
注意:在FileInputStream类中有语句 String name = (file != null ? file.getPath() : null);此代码表示如果我们的File文件对象不存在则我们会自动创建一个File对象
方法
- public int read():每次读取一个字节返回,如果字节已经没有可读的返回-1
InputStream file = new FileInputStream (new File ("src\\cs1.txt"));
// System.out.println ((char) file.read ()); //a
// System.out.println ((char) file.read ());//b
// System.out.println ((char) file.read ());//1
// System.out.println (file.read ());//-1
/**
* 此方法读取代码太过于繁杂,且我们无法得知文件中到底有几个字节,可使用循环来改进
*/
int b;
while ((b = file.read ()) != -1) {
System.out.print ((char) b);
}
file.close();
/**
*此方法无法读取中文,因为它是一个一个字节的读取,因此此方法很少使用,且性能比较慢
*/
- public int read(Byte [] buffer):每次读取一个字节数组返回,如果字节已经没有可读的返回-1
InputStream file = new FileInputStream (new File ("src\\cs1.txt"));
//读中文字符依旧会出现问题,但是解决了性能比较慢的问题,提高了性能
byte [] buffer=new byte[3];
int len;
while ((len = file.read (buffer)) != -1) {
System.out.print (new String (buffer,0,len));
}
file.close();
解决:
定义一个与文件字节一样大的字节数组,一次性读完全部的文件字节但是如果文件过大的时候会造成内存溢出,因此我们读取文件时其实最常使用的是字符流
File files = new File ("src\\cs1.txt");
InputStream file = new FileInputStream (files);
byte[] buffer = new byte[(int) files.length ()];
file.read (buffer);
System.out.println (new String (buffer));
file.close();
FileOutputStream(字节输出流)
作用
以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流
构造器
- public FileOutputStream(File file):创建字节输出流管道与源文件对象接通
- public FileOutputStream(File file,boolean append):创建字节输出流管道与源文件对象接通,可追加数据)
- public FileOutputStream(String filepath):创建字节输出流管道与源文件路径接通
- public FileOutputStream(String filepath,boolean append):创建字节输出流管道与源文件路径接通,可追加数据
注意:我们在创建管道接通时,会先清空文件内的数据然后再写进去被称为覆盖管道,但若在后面再加true则变成追加管道则不会清空文档类的数据
方法
- public void write(int a):写一个字节出去
- public void write(byte[] buffer):写一个字节数组出去
- public void write(byte[] buffer,int pos,int len):写一个字节数组的一部分出去
- flush():刷新流,还可以继续写数据
- close():关闭流,释放资源,但是在关闭之前会先刷新流,一旦关闭,就不能再写数据
File files = new File ("src\\cs1.txt");
OutputStream outputStream = new FileOutputStream (files);//覆盖管道
outputStream.write ('a');
outputStream.write ('v');
outputStream.write ('数');//此种写法会乱码
outputStream.write ("\r\n".getBytes ()); //换行
outputStream.write ("我是测试数组".getBytes ());//将中文字符转换为byte字节数组再次写入进去就不会出现乱码的情况
outputStream.close ();
OutputStream outputStream1 = new FileOutputStream (files, true); //此时将管道变为追加管道
outputStream1.write ("我是追加管道".getBytes ());
outputStream1.close ();
使用字节流完成文件的复制(无论任何类型的文件都可以)
//1、创建一个字节输入流与原文件接通
InputStream inputStream = null;
//2、创建一个字节输出流与目标文件接通
OutputStream outputStream = null;
try {
inputStream = new FileInputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\42页.mp4");
outputStream = new FileOutputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\我是复制的视频.mp4");
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read (bytes)) != -1) outputStream.write (bytes, 0, len);
} catch (Exception e) {
e.printStackTrace ();
} finally {
try {
if (inputStream != null) {
inputStream.close ();
}
if (outputStream != null) {
outputStream.close ();
}
} catch (IOException e) {
e.printStackTrace ();
}
}
手动释放资源代码过于繁琐,在JDK7和JDK9中简化了资源释放代码
JDK7改进方法
try (//这里面只能放置资源对象,用完会自动关闭,自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作
//1、创建一个字节输入流与原文件接通
InputStream inputStream = new FileInputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\42页.mp4");
//2、创建一个字节输出流与目标文件接通
OutputStream outputStream = new FileOutputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\我是复制的视频.mp4");) {
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read (bytes)) != -1) outputStream.write (bytes, 0, len);
} catch (Exception e) {
e.printStackTrace ();
}
JDK9的改进方法
//1、创建一个字节输入流与原文件接通
InputStream inputStream = new FileInputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\42页.mp4");
//2、创建一个字节输出流与目标文件接通
OutputStream outputStream = new FileOutputStream ("D:\\Users\\cczyan\\Desktop\\移通所有作业\\我是复制的视频.mp4");
try (//这里面只能放置资源对象,用完会自动关闭,自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作
inputStream; outputStream
) {
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read (bytes)) != -1) outputStream.write (bytes, 0, len);
} catch (Exception e) {
e.printStackTrace ();
}
什么是资源
FileReader(字符输入流)
定义
用于读取字符流的抽象类。 子类必须实现的唯一方法是read(char [],int,int)和close()。 然而,大多数子类将覆盖这里定义的一些方法,以便提供更高的效率,附加的功能或两者。
作用
以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去
构造器
- public FileReader(File file):创建字符输入流管道与源文件对象接通
- public FileReader(String pathname):创建字符输入流管道与源文件对象接通
方法使用
- public int read():每次读取一个字符返回,如果已经没有可读字符的返回-1
try {
Reader reader = new FileReader ("src\\cs1.txt");
// System.out.println ((char) reader.read ());
// System.out.println ((char) reader.read ());
int ch;
while ((ch = reader.read ()) != -1) {
System.out.print((char) ch);
}
reader.close();
} catch (Exception e) {
e.printStackTrace ();
}
特点:
1、一字符一字符的读写比较慢性能较慢
2、如果编码一致的情况下读取中文字符不会出现乱码现象
- public int read(char[] buffer):每次读取一个字符数组,返回读取的字符个数,如果字符以及没有可读字符的返回-1
try {
Reader reader = new FileReader ("src\\cs1.txt");
// System.out.println ((char) reader.read ());
// System.out.println ((char) reader.read ());
char[] ch = new char[1024];
int len;
while ((len = reader.read (ch)) != -1) {
System.out.println (new String (ch, 0, len));
}
reader.close();
} catch (Exception e) {
e.printStackTrace ();
}
FileWriter(字符输出流)
定义
用于写入字符流的抽象类。 子类必须实现的唯一方法是write(char [],int,int),flush()和close()。 然而,大多数子类将覆盖这里定义的一些方法,以便提供更高的效率,附加的功能或两者。
构造器
- public FileWriter(File file):创建字符输出流管道与源文件对象接通
- public FileWriter(File file,boolean append):创建字符输出流管道与源文件对象接通,可追加数据
- public FileWriter(String filepath):创建字符输出流管道与源文件路径接通
- public FileWriter(String filepath,boolean append):创建字符输出流管道与源文件路径接通 ,可追加数据
方法
- void write(int c):写一个字符
- void write(char[]cbuf) :写一个字符数组
- void write(char[] cbuf,int off,int len):写入字符数组的一部分
- void write(String str):写一个字符串
- void write(String str ,int off,int len):写一个字符串的一部分
- void flush():刷新流
- void close():关闭流
try {
Writer writer = new FileWriter ("D:\\Java\\eclipse\\test1\\src\\cs1.txt");//覆盖输出流
Writer writer1 = new FileWriter ("D:\\Java\\eclipse\\test1\\src\\cs1.txt", true);//追加输出流
writer.write ("a");
writer.write ("测");
char[] a = "我是字符数组".toCharArray ();
writer.write (a);
writer.write ("\r\n");
writer.write (a, 1, 4);
writer.write ("\r\n"); //换行
writer.write ("我是字符串");
writer.write ("\r\n");
writer.write ("我是字符串的一部分的部分", 0, 9);
writer.close ();
} catch (Exception e) {
e.printStackTrace ();
}