#Java中I/O使用入门详解(1)
本文介绍了 FileInputStream,FileOutputStream等常用输入输出流的使用方式,(来自于以前的学习笔记,现整理出来和大家分享).
通俗易懂,老少皆宜O(∩_∩)O~
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* IO的分类:
* 流向:
* 输入流:读取数据
* 输出流:写入数据
* 数据类型:
* 字节流
* 字节输入流 读取数据 InoutStream
* 字节输出流 写入数据 OutputStream
* 字符流
* 字符输入流 读取数据 Reader
* 字符输出流 写入数据 Writer
*
* 注意:一般在探讨IO流,不说的话是按数据类型来说的
*
* 需求:往一个文本文件中写入一句话:"hello,IO".
*
* 分析:
* A:这个最好用字符流实现,这里用字节流
* B:由于我是想往文件中写一句话,所以我们用字节输出流
* 通过上面的分析后我们知道要使用OutputStream
* 但是通过查看API,我们发现该流对象是一个抽象类,不能实例化
* 所以我们要找一个具体的子类,这个时候很简单,实际上,我们是要往文件中写东西
* 文件单词:File
* 然后用的是字节流,连起来就是FileOutputStream
* 注意:每种基类的子类都是以父类名作为后缀名
*
* 查看FileOutputStream构造方法
* FileOutputStream(File file)
* FileOutputStream(String name)
*/
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建字节流输出对象
//FileOutputStream(File file)
// File file= new File("fos.txt");
// FileOutputStream fos=new FileOutputStream(file);
FileOutputStream fos=new FileOutputStream("fos.txt");
/*
* 创建字节输出流对象做了几件事情
* 1:调用系统功能去创建文件
* 2:创建fos对象
* 3:把fos对象指向这个文件
*/
//写数据
fos.write("hello,IO".getBytes());
//释放资源
fos.close();
/*
* 为什么一定要close呢?
* A:关闭流对象,使流对象变成垃圾,以免后面别人接着写
* B:通知系统去释放相关的资源
*/
}
}
##1.FileOutputStream
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 字节输出流操作步骤
* A:创建字节输出流对象
* B:调用write()方法
* C:释放资源
*
* public void write(int b);写一个字节
* public void write(byte[] b);写一个字节数组
* public void write(byte[] b,int Off,int len);写一个字节数组的一部分
*/
public class FileOutputStreaDemo2 {
public static void main(String[] args) throws IOException {
//创建字节流输出流对象
//OutputStream os=new FileOutputStream("fos2.txt);//这是多态
FileOutputStream fos=new FileOutputStream("fox2.txt");
//调用write()方法
fos.write(97);//97----底层是二进制数组----通过记事本打开-----找97对应的字符值----a
//public void write (byte[] b):写一个字节流数组
byte[] bys={97,98,99,100,101};
fos.write(bys);
//public void write(byte[] b,int Off,int len);写一个字节数组的一部分
fos.write(bys,1,3);
fos.close();
}
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 如何实现数据的换行?
* 为什么没有换行呢?因为只写了字节数据,并没有写入换行符号
* 如何实现换行?写入换行符号即可
* 刚才用"\n"我们看到有些文本文件打开是可以的,但用Windows自带却不行
* 原因:不同的系统对于换行符号识别是不一样的
* windows:\r\n
* linux:\n
* Mac:\r
*
* 而一些高级写字本软件可识别任意的换行符的
* 如何实现数据的追加写入?
* 用构造方法待第二个参数为true的情况即可
*/
public class FileOutputStreamDemo3 {
public static void main(String[] args) throws IOException {
//创建字符输出流
//FileOutputStream fos=new FileOutputStream("fos3.txt");
FileOutputStream fos=new FileOutputStream("fos3.txt",true);
//写数据
for(int i=0;i<10;i++){
fos.write(("hello"+i).getBytes());
fos.write("\n".getBytes());
}
fos.close();
}
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 加入异常处理的字节输出流操作
*
*/
public class FileOutputStreamDemo4 {
public static void main(String[] args) {
FileOutputStream fos=null;
try {
fos = new FileOutputStream("fos4.txt");
fos.write("java".getBytes());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally{
//如果fos不是null,才需要close()
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
##2.FileInputStream
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
*字节输入流操作步骤
*A:创建字节输入流对象
*B:调用read()方法读取数据,并把它显示到控制台
*C:释放数据
*
* 读取数据的方式
* A:int read();一次读取一个字节
* B:int read(byte[] b);一次读取一个字节数组
*
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//FileInputStream(String name);
FileInputStream fis=new FileInputStream("fis.txt");
//用int read();
//第一次读取
// int by=fis.read();
// System.out.println(by);
// System.out.println((char)by);
//
// //第二次读取
// by=fis.read();
// System.out.println(by);
// System.out.println((char)by);
// //第三次读取
// by=fis.read();
// System.out.println(by);
// System.out.println((char)by);
//我们发现代码的重复度很高,应该用循环改进
//而用循环,最麻烦的是如何控制循环的条件
//多测两次后发现,读取的结果为-1,说明已经读取到文件的末尾了
//循环改进
// int by=fis.read();
// while(by!=-1){
// System.out.print((char)by);
// by=fis.read();
// }
//最终版代码
int by=0;
//读取,赋值,判断
while((by=fis.read())!=-1){
System.out.println((char) by);
}
//释放资源
fis.close();
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 一次读取一个字节数组
* 返回值是读取字节的
*/
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建字节输入流对象
FileInputStream fis=new FileInputStream("fis2.txt");
//读取数据
//定义一个字节数组
//第一次读取
// byte[] bys=new byte[5];
// int len=fis.read(bys);
// System.out.println(new String(bys,0,len));
//
// byte[] bys =new byte[20];
// int len=0;
// while((len=fis.read(bys))!=-1){
// System.out.println(new String (bys,0,len));
// //System.out.println(new String (bys)此做法有问题,千万要注意
// }
//最终版
//数组的长度一般是1024或者1024的倍数
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
System.out.println(new String (bys,0,len));
}
//释放资源
fis.close();
}
}
##3.一些文件复制应用的例子#
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
*
* 复制文本文件
*
* 数据源:从哪里来
* a.txt 读取数据 FileinputStream
* b.txt 写数据 FileOutputStream
* 目的地:到哪里去
* b.txt
*
* 这一次复制中文没有出现任何问题,为什么?
* 上一次我们出现问题是由于我们把每次获取到一个字节数据,就把该字节数据转换为字符数据
* 而这一次,却是通过IO流读取数据,你读取一个字节,我就写入一个字节,没有存在任何转换
* 他会自己转换
*
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis=new FileInputStream("a.txt");
//封装目的地
FileOutputStream fos=new FileOutputStream("b.txt");
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}
//释放资源(先关谁都行)
fos.close();
fis.close();
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
*
* 复制文本文件
*
* 数据源:从哪里来
* c:\\a.txt 读取数据 FileinputStream
* 目的地:到哪里去
* d:\\b.txt 写数据 FileOutputStream
*
*/
public class CopyFileDemo2 {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis=new FileInputStream("c:\\a.txt");
//封装目的地
FileOutputStream fos=new FileOutputStream("d:\\b.txt");
//复制数据
int by=0;
while ((by=fis.read())!=-1){
fos.write(by);
}
fis.close();
fos.close();
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 需求:把e:\\a.jpg内容复制到当前项目下的aa.jpg中
*
*/
public class CopyImageDemo {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis=new FileInputStream("e:\\a.jpg");
//封装目的地
FileOutputStream fos =new FileOutputStream("aa.jpg");
//复制数据
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}
//释放资源
fos.close();
fis.close();
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 把D:\\a.txt内容复制到E:\\b.txt中
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis=new FileInputStream("d:\\a.txt");
//封装目的的
FileOutputStream fos=new FileOutputStream("e:\\b.txt");
//复制数据
byte[] bys=new byte[1024];
int len=0;
while((len= fis.read(bys))!=-1){
fos.write(bys,0,len);
}
//释放资源
fis.close();
fos.close();
}
}
##4.BufferedOurtputStream与BufferedInputStream#
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 我们通过定义数据的方式的确比以前一个一个读取有效率得多,看来有一个缓冲区是很好的
* 其实java开始设计时,就考虑了这个问题,就专门提供了缓冲区的字节类
* 这种类被称为:缓冲区类(高效类)
* 写数据:BufferedOutputStream
* 读数据:BufferedInputStream
*
* 构造方法可以指定缓冲区大小,但我们一般用不上,因为默认的缓冲区大小就够了
*
* 为什么不传递一个具体的文件或文件路径,而是传送一个OutputStream对象呢?
* 原因很简单,字节缓冲区仅仅提供缓冲区,为高效而设计的,但是呢,真正的读写操作还得靠基本的流对象
*
*/
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws IOException {
//BufferedOutputStream(OutputStream out);
// FileOutputStream fos=new FileOutputStream("bos.txt");
// BufferedOutputStream bos=new BufferedOutputStream(fos);
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("bos.txt"));
//写数据
bos.write("hello".getBytes());
bos.close();
}
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class BufferedInputStreamDemo {
public static void main(String[] args) throws IOException {
//BufferedInputStream(InputDtream in)
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("bos.txt"));
//读数据
// int by =0;
// while((by=bis.read())!=-1){
// System.out.println((char) by);
// }
byte[] bys=new byte[1024];
int len =0;
while ((len=bis.read(bys))!=-1){
System.out.println(new String(bys,0,len));
}
bis.close();
}
}
最后,我们来比较一下四种读写2方式的速度差异:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 把e:\\下的a.mp4复制到当前目录下的aa.mp4
*
* 字节流四种方式复制文件
* 基本字节流一次读写一个字节
* 基本字节流一次读写一个字节数组
* 高效字节流一次读写一个字节
* 高效字节流一次读写一个字节数组
*
*/
public class CopyMp4Demo {
public static void main(String[] args) throws IOException {
long start=System.currentTimeMillis();
//method1("e:\\a.mp4","copy1.mp4");共耗时: 81700ms
//method2("e:\\a.mp4","copy2.mp4");共耗时: 326ms
//method3("e:\\a.mp4","copy3.mp4");共耗时: 1899ms
//method4("e:\\a.mp4","copy4.mp4");共耗时: 137ms
long end=System.currentTimeMillis();
System.out.println("共耗时: "+(end-start)+"ms");
}
//基本字节流一次读写一个字节
private static void method1(String srcString, String destString) throws IOException {
FileInputStream fis=new FileInputStream(srcString);
FileOutputStream fos=new FileOutputStream(destString);
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}
fos.close();
fis.close();
}
//基本字节流一次读写一个字节数组
private static void method2(String srcString, String destString) throws IOException {
FileInputStream fis=new FileInputStream(srcString);
FileOutputStream fos=new FileOutputStream(destString);
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
fos.write(bys,0,len);
}
fos.close();
fis.close();
}
//高效字节流一次读写一个字节
private static void method3(String srcString, String destString) throws IOException {
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream(srcString));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream(destString));
int by=0;
while((by=bis.read())!=-1){
bos.write(by);
}
bos.close();
bis.close();
}
//高效字节流一次读写一个字节数组
private static void method4(String srcString, String destString) throws IOException {
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream(srcString));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream(destString));
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
}
##5.关于I/O使用的小结提纲#
###(1)用于在设备间数据传输的操作
###(2)分类: #
####A:流向
输入流 --> 读取数据
输出流 --> 写入数据
####B:数据类型
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流
a:如果我们没明确说明按照什么分,默认按照数据类型分
b:除非文件用Windows自带记事本打开我们能够读懂,才采用字符流,否则采用字节流
###(3)FilOutoutStream写出数据
####A:操作步骤
a:创建自己人输出流操作对象
b:调用Write()方法
c:释放资源
####B:代码体现:
FileOutputSream fos=new FileOutputStream(“fos.txt”);
fos.write("hello".getBytes());
fos.close();
####C:要注意问题?
a:创建字节输出流对象做了几件事情?
b:为啥要close()?
c:如何实现数据的换行?
d:如何实现数据的追加写入?
####(4)FIleInputStream读取数据
#####A:操作步骤
a:创建字节输入流对象
b:调用read()方法
c:释放资源
#####B:代码实现:
FileInputStream fis =new FileInputStream(“fos.txt”);
//方式一
int by=0;
while((by=fis.read()!=-1)){
System.out.print((char)by);
}
fis.close;
//方式二
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
System.out.print(new String(bys,0,len));
}
fis.close;
###(5)案例:
A:复制文本文件
B:复制图片
C:复制视频
###(6)字节缓冲区流
A:BufferedOutputStream
B:BufferedIntputStream
###(7)例子:几种实现
A:复制文本文件
B:复制图片
C:复制视频