这篇文章给大家介绍一下Java中基本IO操作,希望大家看完这篇文章可以自己完成一个文件的拷贝操作
File
- IO操作就是对文件的操作,在Java万物皆对象的思想下,我们不难想到肯定会有一个类是用来表示文件的。
- Java中用来表示一个文件的类就是File类,使用这个类可以对文件进行一系列的操作,比如打开文件、获取文件路径、获取文件名字等等操作。
- 我们要对文件进行操作,就必须依靠这个对象来打开文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7EbkCxbG-1607167715836)( http://gtwave.gitee.io/image/images/wechart/File对象的部分方法.png)]
大致扫一眼这张图,其实会发现这些方法都是用于操作一个文件,但是并不能操作文件里面的值,那Java中是怎么操作文件的呢?这就要说到Java中的IO流了
Stream
什么是流?
- 当不同的介质之间有数据交互的时候,JAVA就使用流来实现。数据源可以是文件,还可以是数据库,网络甚至是其他的程序
- 也就是说如果需要进行数据的交互,比如说把文件的内容取出来、网络传输这类操作都需要依靠流。
- 在Java中流根据传输的不同方向分为输入流和输出流。
- 输入流:程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道。
- 输出流: 程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。
- 流根据传输的时候根据数据的不同又可以分为字符流和字节流,字符流和字节流就比较好区分了,字符流用于处理存文本信息,字节流可以处理所有信息,因为所有文件都可以转化成二进制的形式。
- 综上,Java就有了四个最基本的抽象类:InputStream、OutputStream,Reader、Writer。Java中所有对流进行操作的类,都直接或间接继承了这四个抽象类的其中一个。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SJ13UVGL-1607167715838)( http://gtwave.gitee.io/image/images/wechart/文件IO操作.png)]
字符流演示
FileReader
public static void main(String arg[])throws Exception {
//打开一个文件
FileReader fileReader = new FileReader("F:/xxx.txt");
//新建一个char数组用来存放数据
char buf[] = new char[1024];
//把内容读进buf数组里面
fileReader.read(buf);
//打印文件内容
System.out.println(new String(buf));
}
- 我们之前说过,InputStream、OutputStream,Reader、Writer都是一个抽象类,那么我们研究的肯定是他们对应的实现类,文章的开头也给大家介绍了一下File这个类,想要打开文件要借助File这个类,所以大胆猜测FileReader就是一个可以打开文件的字符输入流。
- 同样的,InputStream、OutputStream、Writer也都有对应的FileInputStream、FileOutStrea、FileWriter。
- 这里所使用的思想就是装饰器设计模式,这里不对这个设计模式进行展开,这里只要能理解我们可以使用一个方法更多的Reader的实现类来加强字符输入流的功能
体验装饰器设计模式的感觉
public static void main(String arg[])throws Exception {
//File类,只能对文件进行操作,不能对文件内容进行操作
File f = new File("F:/xxx.txt");
//使用FileReader对File类进行增强,这样就可以对文件内容进行操作了
FileReader fr = new FileReader(f);
//继续对FileReader进行增强,br相比于fr会有更多方法,功能更强大
BufferedReader br = new BufferedReader(fr);
}
FileWriter
public static void main(String arg[])throws Exception {
//新建一个字符输出流
FileWriter fw = new FileWriter("F:/xxx.txt");
//向文件写入一个字符串
fw.write("HelloWorld");
//把数据从缓存写入到文件
fw.flush();
}
输出流向文件写入数据的时候使用write方法,但是这个方法会先把数据写入一个缓存,并不会马上写入文件,所以需要调用flush方法才可以成功的把数据写入到文件中。
字符流的操作非常简单,只需记住read方法可以把文件内容读取到输入流,write方法可以将输出流中的数据写入到一个文件。如果需要功能更强大的字符输入流和字符输出流,就去找找Reader与Wirter的实现类,再使用装饰器设计模式进行一个功能的加强就可以了,是不是非常简单呢~
字节流演示
FileInputStream
public static void main(String arg[])throws Exception {
//创建一个FileInputStream对象并打开一个mp3文件
FileInputStream fs = new FileInputStream(new File("E:/wudi.mp3"));
//创建一个buf用来读取输入流中的字节数据
byte[] buf = new byte[1024];
//定义一个变量判断是否文件已经读完了,如果这个变量为-1就说明已经读完了
int n = -1;
//循环读,因为一个文件的大小肯定会有可能大于1204字节,所以需要循环读
while ((n = fs.read(buf)) != -1){
// do something
}
//文件操作结束需要进行关闭,以免浪费资源
fs.close();
}
- 可以看到字节流与字符流还是很相似的,只不过char数组变成了byte数组。
FileOutputStream
public static void main(String arg[])throws Exception {
//创建一个输出流并打开一个文件,如果文件不存在会自动创建
FileOutputStream fo = new FileOutputStream(new File("E:/wudi1.mp3"));
//写入数据,一般需要配合输入流进行循环写入
fo.write(new byte[1024]);
//把数据从缓冲区写入到文件
fo.flush();
//输出流用完也要及时关闭
fo.close();
}
- 将两段代码组合起来完成mp3文件的拷贝
public static void main(String arg[])throws Exception {
//创建一个FileInputStream对象并打开一个mp3文件
FileInputStream fs = new FileInputStream(new File("E:/wudi.mp3"));
//创建一个输出流并打开一个文件,如果文件不存在会自动创建
FileOutputStream fo = new FileOutputStream(new File("E:/wudi1.mp3"));
//创建一个buf用来读取输入流中的字节数据
byte[] buf = new byte[1024];
//定义一个变量判断是否文件已经读完了,如果这个变量为-1就说明已经读完了
int n = -1;
//循环读,因为一个文件的大小肯定会有可能大于1204字节,所以需要循环读
while ((n = fs.read(buf)) != -1){
// do something
}
//文件操作结束需要进行关闭,以免浪费资源
fs.close();
//把数据从缓冲区写入到文件
fo.flush();
//输出流用完也要及时关闭
fo.close();
}
- 运行这段代码就可以拷贝文件啦~
commons-io
在Java中也有一个专门处理IO操作的jar包
改进一下拷贝mp3文件的操作
public static void main(String arg[])throws Exception {
//创建一个FileInputStream对象并打开一个mp3文件
FileInputStream fs = new FileInputStream(new File("E:/wudi.mp3"));
//创建一个输出流并打开一个文件,如果文件不存在会自动创建
FileOutputStream fo = new FileOutputStream(new File("E:/wudi1.mp3"));
//使用IOUtils包的方法进行拷贝
IOUtils.copy(fs,fo);
//文件操作结束需要进行关闭,以免浪费资源
fs.close();
//把数据从缓冲区写入到文件
fo.flush();
//输出流用完也要及时关闭
fo.close();
}
- 这样是不是简洁了很多呢,而且这个包是apache开发的包,所以我们也可以避免写循环的时候出现的一些错误。
- 这个包里面所带的方法也非常的丰富,大家可以自行探索一下,以后处理IO操作就可以用这个包来简化操作了。