file对象不能操作文件中的内容——>所以我们需要通过I/O的方式来完成
文件是存储在硬盘上的(永久性保存 不会因为JVM虚拟机的停止 回收内存空间 而消失)
因为文件不在内存中 所以需要通过I/O操作文件
读取文件中的信息in 将信息写入文件中out
文件流按照读取或写入的单位(字节数)大小来区分
四个基础流—->低级流
字节型文件流(1字节)
FileInputStream 读
FileOutputStream 写
字符型文件流(2字节 即1字符)
FileReader 读
FileWriter 写
字节流 好处 什么类型的文件都可以处理
不好处 处理纯文本的文件可能会产生乱码的问题
如文件中的内容为 abcd我 读取byte[5]的数组 读到 我 这个字的时候会被拆分 拆分完之后再重组就会出现问题
字符流 只能操作纯文本文件(文件右键用记事本打开 能看懂的就是纯文本 注意.docx不是纯文本)如 .txt .html
FileInputStream 读
1.java.io包
2.继承关系
继承 InputStream类 它是字节型输入流的父类
3.创建对象
没有无参数的构造方法
常用的两个:
3.1 带File类型的构造方法
try {
File file = new File("E:/test/TestFile.txt");
//file对象创建时路径给错了也没事 只是建立不起映射的关系而已
FileInputStream fis = new FileInputStream(file);
//带File参数的构造方法
int code = fis.read();//这个方法每次只读取一个字节 因为路径不对的话读不到文件 会出现异常 所以处理异常
while(code!=-1){//如果文件里面没东西了 就返回-1
System.out.println((char)code);
code = fis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//创建FileInputStream对象后 因为我们是要去读文件 所以文件路径不能错
//所以创建FileInputStream对象不管怎么样都会出现编译时异常 要求我们必须处理
3.2 带String类型的构造方法(路径)
try {
FileInputStream fis = new FileInputStream("E:/test/TestFile.txt");
//带String参数的构造方法
byte[] b = new byte[5];
int count = fis.read(b);//去文件里读东西 装入数组内
//这里的 count 是读取到的有效的字节个数
while(count!=-1){
String value = new String(b,0,count);//这个方法就不会出现问题 从0开始 count里面有几个就读取几个
//如果是 String value = new String(b); 读数据会有小问题
//第一次 a b c d e
//第二次 f g \r \n h
//第三次 i j k l m
//第四次 \r \n o(l m)
//读到第四次的时候因为数组没有填满 所以里面还留着上一次读到的信息 所以输出的时候会把 上一次读取的 没被覆盖掉的 也输出出来
System.out.print(value);
count = fis.read(b);
}
} catch (IOException e) {
e.printStackTrace();
}
4.常用方法
4.1 int code = read();
//每次从流管道中读取一个字节
//每读到内容返回-1
//注意read不是直接从文件里读的 而是通过 file对象 来搭建 FileInputStream对象与硬盘中的文件 读取的桥梁 类似于管道
//每次读取的字节都 从硬盘中流出 进入管道 经过file对象 最后流入 fileInputStream对象
4.2 int count = read(byte[]);
//每次从流管道中读取若干个字节 存入数组内(注意不是读数组) 再将数组里的东西拿出来干活
4.3 int count = read(byte[],int offset,int len);
//读取流管道中 从offset开始 长度为len 的字节 存入数组内
4.4 int count = available();
//流管道中还有多少缓存的字节数
4.5 skip(long);
//跳过几个字节后再往后读
//可以通过多线程来同时读取文件
*4.6 close();
//注意关闭的是流通道 不是file对象 读取文件之后必须要关闭 所以close()一般放在finally中
如
FileInputStream fis = null;
//因为创建时如果放在try中 fis生命周期 在try执行完后就没有了 所以需要把它放在外面创建
//但是又不能直接用构造方法 它会提示我们要处理异常 所以我们可以先赋值为null
try {
fis = new FileInputStream("E:/abc");
//注意这里也可能出现问题 如果路径不对 就是会出现异常 FileNotFoundException文件无法找到异常
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fis!=null){
fis.close();//如果 fis没new出来 那么此时fis 是null的 如果直接用就会出现空指针异常
}
} catch (IOException e) {
e.printStackTrace();
}
}
FileOutputStream 写
1.java.io包
2.继承关系
继承 OutputStream类 它是字节型输出流的父类
3.创建对象
没有无参数的构造方法
带File类型的构造方法**(file[,boolean])//**后面的参数是用来判断是否要创建新的文件
try {
File file = new File("E:/test/test.txt");
FileOutputStream fos = new FileOutputStream(file,true);
//带file类型的构造方法 创建文件输出流 即使路径有问题 也不会出现异常 它会直接帮我们创建一个新的文件
//如果调用的是没有append(true)参数的构造方法 每次往里写东西 即使已经有这个文件 系统都会默认创建新的文件
fos.write(97);//a
//fos对象写的 a 是写到管里了
fos.flush();
//刷新 意思 是将管道中的字节推入文件中
System.out.println("写入完毕!");
} catch (IOException e) {
e.printStackTrace();
}
带String类型的构造方法(path[,boolean])//后面的参数是用来判断是否要创建新的文件
FileOutputStream fos = null;
try {
fos = new FileOutputStream("E:/test/ccc.txt",true);
//带String参数的构造方法
String str = "1+1=2";
byte[] b = str.getBytes();
fos.write(b);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos!=null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
4.常用方法
4.1 write(int code);
//将给定的code对应字符写入文件
4.2 write(byte[]);
//将数组中的全部字节写入文件 可以通过getByte()方法将String类型的写入文件
4.3 write(byte[],int offset,int len);
//将数组中 从offset开始 长度为len 的字节写入文件
4.4 flush();
//将管道中的字节推入文件
4.5 *close();
//关闭
字符型文件流
- java.io包
2. FileReader 继承 InputStreamReader 再继承 Reader
FileWriter 继承 OutputStreamReader
3. 构造方法
与字节流一样
4. 常用方法
只是数组由 byte[] 变为了 char[]
read(); read(char[]);
write(int); write(char[]); write(String);
其他都与字节流一样