IO流
流,一端移动到另一端,流是一个抽象、动态的概念,是一连串连续动态的数据集合(IO,in&out)
数据流从数据源与程序间传输,以程序为中心,进为输入流,出为输出流
核心类
类 | 说明 |
---|---|
File | 文件类 |
InputStream | 字节输入流 |
OutputStream | 字节输出流 |
Reader | 字符输入流 |
Writer | 字符输出流 |
Closeable | 关闭流接口 |
Flushable | 刷新流接口 |
Serializable | 序列化接口 |
- 字节流:按照字节读取数据
- 字符流:按照字符读取数据,由于对文件的编码不同,所以有了对字符进行高效操作的字符流对象。
原理:底层还是基于字节流操作,自动搜寻了指定的码表。(字符集)
码表不对的话会出现乱码情况
API里面调用的类没有显示构造方法
可能使用构造器创建对象会有问题或者私有构造器
主要分为两种:
1。工具类,直接类.方法调用(静态方法)
2。静态方法返回了该类的对象(静态工厂方法)
Runtime.getRuntiime()该方法返回与当前应用程序相关的Runtime对象
名称分割符/
D:/eclipse/testSchoolTeamFile01/src/user.db(路径)
也可以使用常量拼接
“D:”+File.separator+“eclipse”+File.separator+“testSchoolTeamFile01”+
File.separator+“src”+File.separator+“user.db”
与上面效果一致
file.length()也可以查看大小
File对象的创建方法 1直接用地址 2可以拆分 File src = new
File(“D:/eclipse/testSchoolTeamFile01/src”,“user.db”); src = new
File("D:/eclipse/testSchoolTeamFile01’’,“src/user.db”) 拆分的格式没有限制
3父对象子名称 src = new File(new
File(“D:/eclipse/testSchoolTeamFile01/src”),user.db);
相对路径和绝对路径
1)存在盘符:绝对路径
2)不存在盘符:相对路径,以工程为出发点
src = new File(“user.db”);
(相对于当前的工程)
可以使用src.getAbsolutePath()结果与上同
File下的基本方法
文件方法
API | 说明 |
---|---|
*pathSeparator *separator | 路径、路径分割符 |
*File(String parent , String child) *File(File parent , String child) File(String name) | 构造器,没有盘符以当前工程目录作为相对目录 |
getName()获取File名称getPath()获取构建时路径getAbsolutePath()返回绝对路径getParent()返回父路径 | 文件名、路径名 |
exists() isFile() isDirectory() | 判断状态 |
length() | 文件长度(首先要是文件) |
createNewFile() ,不存在才创建 delete() | 创建新文件 ,删除文件 |
像con。com3等等。。。这类文件名可能是系统设备名,不能创建
目录方法
mkdir()找到上级目录才创建最后一级目录 | mkdirs() 创建目录,如果父目录链不在一同创建 |
---|---|
list()列出下级名称,用字符串数组接收 | 下级名称 |
listFiles()列出下级对象,返回一个容器(File类型数组) | 下级File |
listRoots() | 根路径 ,列出所有盘符,类型同上 |
创建的方法一般返回一个布尔值,用一个布尔类型变量接收
File类型——打印出的是文件路径
统计文件夹大小
```java
```java
```java
package testingDate;
/*
* 测试统计文件夹的大小
*
*
* */
import java.io.File;
public class TestBIgger {
public static void main(String[] ags) {
File src = new File("D:\\qq\\Plugin");
count(src);
System.out.println(len);
}
private static long len = 0;
public static void count(File src) {
//获取大小
if(null!=src&&src.exists()) {
System.out.println("1");
if(src.isFile()) {
len+=src.length();
System.out.println("2");
}else
for(File s:src.listFiles()) {
//将所有的File对象取到s中计数
System.out.println("3");
count(s);
//对子代重复操作
}
}
}
}
四个抽象类
InputStream,字节输入流的父类,数据单位为字节 | 常用方法int read () void close() |
---|---|
OutputStream,字节输出流的父类,数据单位为字节 | void write(int) void flush() void close() |
Reader,字符输入流的父类,数据单位为字符 | int read() void close() |
Writer,字符输出流的父类,数据单位为字符 | void write (String) void flush() void close () |
InputStream
提供Closeable方法,通知操作方法关闭有关的系统资源(close())
- read()从输入流中读取数据的下一个字节
- read(byte【】b)从输入流中读取一些字节数,并且将它们储存到缓冲器阵列b
OutpuStream
与输入流对应的
提供了Closeable()Flushable()//写出资源是有时要手动清除一些缓存,AutoCloseable()(自动关闭)
需要补充(为避免数据驻留在内存中,进行一段输出就可以刷新一下,关闭自动刷新) - 对应方法:close() flush()刷新此输出流并强制任何缓冲耳朵输出字节被写出。 write(int b)将指定的字节写进输出流
- write(byte【】 b, int off,int len)//从指定的字节数组写入len字节,从偏移量开始输出到此输出流。
- write(byte【】 b)将b.length字节从指定的字节数组写入此输出流。
Reader
字节流处理一切文件,字符流处理可见字符
同样该抽象类定义了Closeable,AutoCloseable,Readable - read()读取一个字符
- read(char【】cbuf)将字符读入数组
- read(char【】 cbuf,int off,int len)将字符读入数组的一部分
Writer
与Reader对应
抽象类定义了Closeable,Flushable,Appendable(写入;重头覆盖,从尾追加),AutoCloseable - write(int c)写一个字符
- write(String str)写一个字符串
- write(String str ,int off ,int len)写一个字符串的一部分
- write(char【】sbuf)写入一个字符数组
- write(char【】sbuf,int off ,intlen)写入字符数组的一部分
IO流的标准步骤
创建源(来源)、选择流(字符/字节具体的子类)、操作(读写,范围)、释放
package com.school.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/*
*
* IO流学习1
* 1.创建源
* 2.选择流
* 3.具体操作
* 4.释放资源
*
*
* */
public class IOTest01 {
public static void main(String[] args) {
//1.创建源
File src = new File("D:/c.txt");
//给出相对路径(本文件夹下),注意:读取内容的时候是不能直接操作文件夹的
//想要操作文件夹需要利用到递归
//2.选择流
InputStream is = null;
//在外面定义以便finally中调用来在出现异常时清除缓存(里面定义找不到)
try {
is = new FileInputStream(src);
//3.操作(读取)
//int temp;
//while ((temp=is.read())!=-1) {
//System.out.println((char)temp);
//}
//上面会和下面抢着读取hhh
int data1 = is.read();//第一个数据h
int data2 = is.read();//第二个数据e
int data3 = is.read();//第三个数据l
int data4 = is.read();//第四个没有
System.out.print((char)data1);
System.out.print((char)data2);
System.out.print((char)data3);
System.out.print(data4);
//不存在的数据read()返回-1
//4.释放资源
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(null!=is) {
//为了避免is还没打开就报异常,到finally这没有is导致出问题
is.close();
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
文件拷贝(实际上就是一个输入再一个输出)
write的第二个参数偏移量: 其实偏移量 真正指的是这个存放数据的数组的偏移量(第一个参数)。
使用这个解释去理解一下这个示例。
读取3个字节(第三个参数)的数据,存放在bytes数组中(第一个参数),存放在数组中的什么位置呢?那就得看偏移量了,这里偏移量是2(第二个参数),就表示存放在数组中下标为2的位置开始,数据依次往后展开。也就是说,假设读取了两个字节的数据,就放在数组的3、4号坑(数组是从0开始的),假设读取了3个字节的数据,就放在数组的3、4、5号坑…(转载)
字节数组流
java借助操作系统调用硬盘里的文件,需要清除缓存 将源头换为另一个——某位置上的一个内存(字节数组)
java可以直接访问,由垃圾处理机制来释放的,故不需要释放
任何数据均可以被转化为字节数组,使用字节数组流方便进行传输
内存传输快,量少(数据尽可能小)