文章目录
- 一、IO流操作的基本步骤
- 二、创建源
- 三、选择流
- 1.FileInputStream文件输入流
- 2.FileOutputStream文件输出流
- 3.FileReader字符文件输入流
- 4.FileWriter字符文件输出流
- 5.ByteArrayInputStream字节数组输入流
- 6.ByteArrayOutputStream字节数组输出流
- 7.BufferedInputStream字节缓冲输入流
- 8.BufferedOutputStream字节缓冲输出流
- 9.BufferedReader字符缓冲输入流
- 10.BufferedWriter字符缓冲输出流
- 11.DataInputStream/DataOutputStream数据流
- 12.ObjectInputStream/ObjectOutputStream对象流
- 13.PrintStream/PrintWriter打印流
- 四、IO小练习
一、IO流操作的基本步骤
1)创建源 2)选择流 3)操作 4)释放资源
二、创建源
1.以文件为源
创建File对象
(官方解释:File类:文件和目录路径名的抽象表示)
File对象的创建形式:
//1.直接路径构建(可为绝对路径或相对路径)
File src = new File("IO.txt");
//2.可以传入父子路径
File src = new File("D:/Java","/src/IO.txt");
//3.可以传入:父对象,子路径
File src = new File(new File("D:/Java/src"),"IO.txt");
File的常用方法及使用:
//返回文件的长度,文件夹为0,未创建的文件夹也为0
long len = src.length();
//返回当前文件或目录的名称
String name = src.getName();
//将此抽象路径名转换为路径名字符串,构建时使用相对路径就返回相对路径,绝对路径就返回绝对路径
String path = src.getPath();
//返回绝对路径名字符串
String absPath = src.getAbsolutePath();
//返回此抽象路径名的父目录的路径名字符串
String parPath = src.getParent();
//返回此抽象路径名的父目录的抽象路径名(父对象)
File parSrc = src.getParentFile();
//当抽象路径表示的文件不存在时,创建一个空文件
boolean flag = src.createNewFile();
//删除此抽象路径名表示的文件或目录
boolean flag = src.delete();
//补充
//显示当前用户目录
String str = System.getProperty("user.dir");
//类的内部域中:与系统相关的默认名称分隔符
//separator-->String separatorChar-->char
System.out.println(File.separator);//输出 /
//判断此抽象路径名表示的文件是否是普通文件
boolean flag = src.isFile();
//判断此抽象路径名表示的文件是否为目录
boolean flag = src.isDirectory();
//判断此抽象路径名表示的文件或目录是否存在
boolean flag = src.exists();
//文件操作
File src = new File("IO.txt");
if(src == null || !src.exist()){
System.out.println("文件不存在");
}else}{
if(src.isFile()){
System.out.println("文件操作");
}else{
System.out.println("文件夹操作");
}
}
File dir = new File("IO.txt");
//文件夹操作
//创建有此抽象路径名命名的目录,若上级目录存在,则创建成功,否则失败
boolean flag = dir.mkdir();
//上级目录可以不存在,不存在一同创建
boolean flag = dir.mkdirs();
//列出下级文件和目录的名称
String[] subNames = dir.list();
//列出下级文件和目录的File对象
File[] subFiles = dir.listFiles();
//列出所有盘符对象
File[] subFiles = dir.listRoots();
//使用递归实现打印子孙级目录和文件的名称
public class DirName{
public static void main(Stirng[] args){
File src = new File("D:/Java");
printName(src);
}
private static void printName(File src){
System.out.println(src.getName());
if(src == null || !src.exist()){
return;
}else if(src.isDirectory()){
for(File s : src.listFiles()){
printName(s);
}
}
}
}
//统计文件夹的大小
public class DirSize{
public static void main(String[] args){
File src = new File("D:/Java");
count(src);
System.out.println(length);
}
private static long length = 0;
private static void count(File src){
if(src!=null && src.exist()){
if(src.isFile()){
length+=src.length();
}else{
for(File s : src.listFiles())
count(s);
}
}
}
}
2.以字节数组为源
//编码:字符串-->字节数组
String str = "世界你好";
byte[] datas = str.getBytes();//默认使用工程的字符集
datas = str.getBytes("GBK");//以GBK形式进行编码
//解码:字节数组-->字符串
String msg = new String(datas,0,datas.length,"utf-8");
三、选择流
以文件为源的流
1.FileInputStream文件输入流
- 从文件系统中的文件获取输入字节
流的创建:
//方式一
File src = new File("IO.txt");
InputStream is = new FileInputStream(src);
//方式二
InputStream is = new FileInputStream("IO.txt");
流的常用方法:
//从该输入流中读取一个字节的数据,返回该字节的编码
int tmp = is.read(); char ch = (char)tmp;
//从该输入流读取最多b.length个字节的数据到一个字节数组,返回读取的内容的长度
byte[] b = new byte[1024];
int len = is.read(b);
//最多读取k个字节数据到字节数组
int len1 = is.read(b,0,k);
//读取操作
byte[] flush = new byte[1024]; //缓冲容器
int len = -1;
while((len=is.read(flush))!=-1){
String str = new String(flush,0,len);
System.out.print(str);
}
2.FileOutputStream文件输出流
- 用于将数据写入File或FileDescriptor的输出流中
流的创建:
//方式一
File dest = new File("IO.txt");
OutputStream os = new FileOutputStream(dest);
//方式二
OutputStream os = new FileOutputStream("IO.txt");
//方式三,在当前文件的内容之后写入文件数据
OutputStream os = new FileOutputStream("IO.txt",true);
流的常用方法:
//将b.length字节从指定的字节数组写入此文件输出流
byte[] b = "Hello world".getBytes();
os.write(b);
//或者从off开始的len个字节写入此文件输出流
os.write(b,0,b.length);
3.FileReader字符文件输入流
- 阅读字符文件
流的创建:(参照FileInputStream对比)
//方法一
File src = new File("IO.txt");
Reader reader = new FileReader(src);
//方法二
Reader reader = new FileReader("IO.txt");
流的常用方法:
//读一个字符
int tmp = reader.read();
//分段读取
char[] flush = new char[1024];
int len = -1;
while((len=reader.read(flush))!=-1){
String str = new String(flush,0,len);
System.out.println(str);
}
此处与FileInputStream的区别在于传进read()的参数为char类型而非byte类型
4.FileWriter字符文件输出流
流的创建:
//方式一
File dest = new File("IO.txt");
Writer writer = new FileWriter(dest);
//方式二
Writer writer = new FileWriter("IO.txt");
//方式三,在当前文件的内容之后写入文件数据
Writer writer= new FileWriter("IO.txt",true);
流的常用方法:
//写出操作
//方法一,以字符数组的形式写入输出流
char[] datas = "Hello world".toCharArray();
writer.write(datas,0,datas.length);
//方法二,以字符串的形式写入输出流
String msg = "hello,world";
writer.write(msg,0,msg.length());
//方法三,append字符串
writer.append("Hello\r\n").append("world");
writer.flush();
以字节数组为源的流
5.ByteArrayInputStream字节数组输入流
- 从字节数组中读出数据
(源为字节数组而非文件)
流的创建:
//创建输入的参数为字节数组而非File对象
byte[] src = "The world is beautiful".getBytes();
InputStream is = new ByteArrayInputStream(src);
流的常用方法: read
与FileInputStream相类似
6.ByteArrayOutputStream字节数组输出流
- 实现了将数据写入字节数组的输出流中
(注意此种流与前几种流有些不同)
流的创建:(创建不需使用源)
//因在子类中增加了新的方法,所以为了使用子类中的方法,不能使用多态
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//创建一个新的字节数组输出流,具有指定大小的缓冲区容量(以字节为单位)
ByteArrayOutputStream baos = new ByteArrayOutputStream(10);
流的常用方法:
//write方法和FileOutputStream相同
//创建一个新分配的字节数组
byte[] dest = baos.toByteArray();
//返回缓冲区当前的大小
int len = baos.size();
缓冲流
7.BufferedInputStream字节缓冲输入流
流的创建:
InputStream is = new BufferedInputStream(new FileInputStream("IO.txt"));
//可以指定缓冲区大小
InputStream is = new BufferedInputStream(new FileInputStream("IO.txt",1024));
流的常用方法: 与FileInputStream相类似
8.BufferedOutputStream字节缓冲输出流
流的创建:
OutputStream os = new BufferedOutputStream(new FileOutputStream("IO.txt"));
//可以指定缓冲区大小
OutputStream os = new BufferedOutputStream(new FileOutputStream("IO.txt",1024));
流的常用方法: 与FileOutputStream相类似
9.BufferedReader字符缓冲输入流
- 从字符输入流读取文本,缓冲字符
流的创建:
Reader reader = new BufferedReader(new FileReader("IO.txt"));
//可以指定缓冲区大小
Reader reader = new BufferedReader(new FileReader("IO.txt"),1024);
流的常用方法:
//read与FileReader中read相类似
//readLine()读取一行文字
String line = reader.readLine();
10.BufferedWriter字符缓冲输出流
- 将文本写入字符输出流,缓冲字符
流的创建:
Writer writer = new BufferedWriter(new FileWriter("IO.txt"));
//可以指定缓冲区大小
Writer writer = new BufferedWriter(new FileWriter("IO.txt"),1024);
流的常用方法:
//write与FileWriter中write相类似
//newLine()换行
writer.newLine();
11.DataInputStream/DataOutputStream数据流
流的创建:
DataOutputStream dos = new DataOutputStream(new ByteArrayOutputStream());
byte[] datas = baos.toByteArray();
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(datas));
流的常用方法:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
dos.writeUTF("hello");
dos.writeInt(2);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas = baos.toByteArray();
//读取
DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new ByteArrayInputStream(datas)
));
//顺序与写出一致
String msg = dis.readUTF();
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(flag);
12.ObjectInputStream/ObjectOutputStream对象流
public class ObjectTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));
oos.writeUTF("hello");
oos.writeInt(2);
oos.writeBoolean(false);
oos.writeChar('a');
//写入对象 -->序列化
oos.writeObject("world");
oos.writeObject(new Date());
Employee emp = new Employee("Jack",400);
oos.writeObject(emp);
oos.flush();
byte[] datas = baos.toByteArray();
//读取-->反序列化
ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(
new ByteArrayInputStream(datas)
));
//顺序与写出一致
String msg = ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
System.out.println(flag);
//对象的数据还原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();
if(str instanceof String){
String strObj = (String)str;
System.out.println(strObj);
}
if(date instanceof Date){
Date dateObj = (Date)date;
System.out.println(dateObj);
}
if(employee instanceof Employee){
Employee empObj = (Employee)employee;
System.out.println(empObj.getName() + "-->"+empObj.getSalary());
}
}
}
//JavaBean封装数据
class Employee implements java.io.Serializable{
private transient String name; //该数据不需要序列化
private double salary;
public Employee() {
}
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
13.PrintStream/PrintWriter打印流
//打印流System.out
PrintStream ps = System.out;
ps.println("打印流");
ps.println(true);
ps = new PrintStream((
new BufferedOutputStream(
new FileOutputStream("print.txt"))),true);
ps.println("打印流");
ps.println(true);
ps.close();
//重定向输出端
System.setOut(ps);
System.out.println("change");
//重定向回控制台
System.setOut(new PrintStream((
new BufferedOutputStream(
new FileOutputStream(FileDescriptor.out))),true));
System.out.println("i am backing ..");
四、IO小练习
1.复制操作
public class Copy {
public static void main(String[] args) {
copy("IO.txt","IO_copy.txt");
}
private static void copy(String srcPath,String destPath){
File src = new File(srcPath);
File dest = new File(destPath);
try(InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest)){
byte[] flush = new byte[1024];//缓冲容器
int len = -1;
while((len=is.read(flush))!=-1){
os.write(flush,0,len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
补充:字符流底层还是基于字节流操作,自动搜寻了指定的码表。