输入流与输出流
在程序中所有的数据都是以流的方式进行传输或保存的,在流操作中存在有输入流和输出流的概念
操作流分类:
- 字节操作流(是在JDK 1.0的时候定义的):OutputStream、InputStream
- 字符操作流(是在JDK 1.1的时候定义的):Writer、Reader
流程:
1.如果要操作的是文件,那么首先要通过File类对象找到一个要操作的文件路径(路径可能存在,也可能不存在,如果不存在要创建路径)。
2.通过字节流或者字符流的子类为字节流或字符流的对象实例化
3.执行读/写操作
4.一定要关闭操作的资源(close()),不管随后代码如何操作,资源永远要关闭。
16.2.1 OutputStream字节输出流
字节是(Byte)是进行I/O操作的基本数据单位,在程序进行字节数据输出时可以使用java.io.OutputStream类完成,此类定义如下:
pubic abstract class OutputStream extends Object implements Closeable,Flushable{}
OutputStream字节输出流
范例:使用OutputStream类实现内容输出
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaIODemo403 {
public static void main(String[] args) {
//1.文件路径
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
if(!file.getParentFile().exists()) { //如果父目录不存在
file.getParentFile().mkdirs(); //创建父路径
}
OutputStream out=null;
//2.通过子类实例化
try {
out=new FileOutputStream(file);
String str="今天星期六";
out.write(str.getBytes()); //3.将字符串变为字节数组
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally { //4.关流
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
执行结果
范例:文件内容追加
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaIODemo403 {
public static void main(String[] args) {
//1.文件路径
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
if(!file.getParentFile().exists()) { //如果父目录不存在
file.getParentFile().mkdirs(); //创建父路径
}
OutputStream out=null;
//2.通过子类实例化
try {
out=new FileOutputStream(file,true);
String str="今天星期六\r\n";
out.write(str.getBytes()); //3.将字符串变为字节数组
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally { //4.关流
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
执行结果
16.2.2 InputStream字节输入流(读取)
此类结构定义:
public abstract class InputStream extends Object implements Closeable{}
InputStream字节输入流
InputStream数据读取操作
读取单个字节
读取多个字节
范例:使用InputStream类读取文件内容
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class JavaIODemo405 {
public static void main(String[] args) {
//1.文件路径
File file=new File("E:"+File.separator+"lilei"+File.separator+"ff.txt");
InputStream input=null;
if(file.exists()) {
try {
input=new FileInputStream(file); //2.子类实例化
byte data[]=new byte[1024]; //3.创建字节数组 ,用来存储,数据读取缓冲区
int len=input.read(data); //读取数据,将数据读取到缓冲区中,同时返回读取的字节个数
System.out.println(new String(data,0,len)); //4.字节转为字符串
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(input!=null) {
try {
input.close(); //5.关流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
执行结果
今天星期六今天星期六
今天星期六
今天星期六
今天星期六
今天星期六
今天星期六
范例:读取全部内容
package cn.mldn.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class JavaIODemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" +
File.separator + "mldn.txt"); // 输出文件路径
if (file.exists()) { // 文件存在
InputStream input = new FileInputStream(file) ;// 文件输入流
byte data [] = input.readAllBytes() ; // 读取全部数据
System.out.println("【" + new String(data) + "】");
input.close(); // 关闭输入流
}
}
}
16.2.3 Writer字符输出流
Writer类定义
public abstract class Writer extends Object implements Closeable, Flushable, Appendable{}
writer类常用方法
范例:使用FileWriter类实现数据输出
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class JavaIODemo407 {
public static void main(String[] args) {
//1.文件路径
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目录必须存在,不存在创建
file.getParentFile().mkdirs();
}
Writer writer=null;
try {
writer=new FileWriter(file); //2.子类实例化
//3.输出字符串
writer.write("今天好好学习!");
writer.append("加油");
} catch (IOException e) {
e.printStackTrace();
}finally { //4.关流
if(writer!=null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
执行结果
16.2.4 Reader字符输入流
Reader定义
public abstract class Reader extends Object implements Closeable, Readable{}
Reader是实现字符输入流的操作类,可以实现char数据类型的读取
范例:文件内容读取
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class JavaIODemo408 {
public static void main(String[] args) throws IOException {
//1.文件路径
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
Reader in=null;
if(file.exists()) {
//2.子类实例化
try {
in=new FileReader(file);
//3.缓冲区
char [] data=new char[1024];
//4.读取数据
int len=in.read(data);
System.out.println(new String(data,0,len));
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
in.close();//5.关流
}
}
}
}
执行结果
今天好好学习!加油
16.2.5 字节流与字符流区别
数据传输(或者将数据保存在磁盘)时所操作的数据依然为字节数据,字符数据都是通过缓冲区来进行处理后得到的内容。
两类操作最大的区别,就在于字符流使用了缓冲区(这样更适合于中文数据的操作),而字节流是直接进行数据处理操作。所以当使用字符输出流进行输出时就必须使用Flushable接口中提供的flush()方法强制性刷新缓冲区中的内容,字符流如果不使用close()方法。否则数据将不会输出。
范例:字符流输出并强制刷新缓冲区
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class javaIODemo409 {
public static void main(String[] args) {
//1.文件路径
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目录必须存在,不存在创建
file.getParentFile().mkdirs();
}
try {
Writer writer=new FileWriter(file); //2.子类实例化
//3.输出字符串
writer.write("今天好好学习!");
writer.append("加油");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行结果
16.2.6 转换流
转换流的设计目的是为了解决字节流与字符流之间操纵类型的转换,java.io包中提供有两个转换流:OutputStreamWriter、InputStreamReader
OutputStreamWriter类继承结构
InputStreamReader类继承结构
范例:实现OutputStream与Writer转换
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class JavaIODemo411 {
public static void main(String[] args) {
File file=new File("E:"+File.separator+"File"+File.separator+"lilei"+File.separator+"ll.txt");
if(!file.getParentFile().exists()) { //父目录必须存在,不存在创建
file.getParentFile().mkdirs();
}
OutputStream output=null;
Writer out =null;
try {
output=new FileOutputStream(file); //字节流
out =new OutputStreamWriter(output); //字节流转字符流
out.write("早起早睡,身体好!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
out.close();
output.close(); //倒着关流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
执行结果
16.2.7 文件复制
package com.lxh.sixteenchapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class JavaIODemo412 {
public static void main(String[] args) {
if(args.length!=2) {
System.out.println("命令执行错误,拷贝失败!");
System.exit(1);
}
long start=System.currentTimeMillis();
FileUtil fu=new FileUtil(args[0],args[1]);
System.out.println(fu.copy()?"文件拷贝成功":"文件拷贝失败");
long end=System.currentTimeMillis();
System.out.println("花费时间:"+(end-start));
}
}
class FileUtil{ //拷贝工具类
private File srcFile; //源文件路径
private File desFile; //目标文件路径
public FileUtil(File srcFile, File desFile) { //接收复制路径
this.srcFile = srcFile; //保存源文件路径
this.desFile = desFile; //保存目标文件路径
}
public FileUtil(String src, String des) { //接收复制路径
this(new File(src),new File(des)); //调用构造
}
public boolean copy() {
if(!srcFile.getParentFile().exists()) { //源文件必须存在
System.out.println("拷贝源文件不存在");
return false;
}
if(desFile.getParentFile().exists()) { //目标文件不存在,则需要创建
desFile.getParentFile().mkdirs();
}
byte data[] =new byte[1024]; //开辟一个拷贝缓冲区
InputStream in=null;
OutputStream out=null;
int len=0;
try {
in=new FileInputStream(this.srcFile);
out=new FileOutputStream(this.desFile);
while((len=in.read(data))!=-1) {
out.write(data,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
}
执行结果
文件拷贝成功
花费时间:136