在变量,数组和对象中储存数据是暂时储存在的,程序结束后它们就会消失。想要永久的储存程序创建的数据,就需要将其保存在磁盘文件中,而中只有数据储存起来才可以在其他程序中使用它们java的I/O技术可以将数据保存起来到文本文件中,二进制文件甚至是ZIP压缩文件,以达到永久性保存数据的要求 掌握I/O处理技术能够提高对数据的处理能力
15.1输入/输出流
流是一组有序的数据,根据操作的类型,可分为输入流和输出流两种,I/O(Input/Output。输入。输出)流提供了一条通道程序 可以使用这条通道把园中的字节序列送到目的地,虽然I/O流通常与磁盘文件存取有关,但程序的源和目的地也可以是键盘,鼠标,内存或者显示器窗口等
输入流
InputStream类字节输入流的抽象类,它是所有字节输入流的父类 (主要内容就不一一叙述)
输出流
OutputStream类是字节输出流的抽象类,此抽象类是表示输出的字节流的所有类的超类
15.2File类
File类是java.io包中唯一代表磁盘文件本身的累 。File累定义了一些平台无关的方法来操作文件可以通过调用File类中的方法来实现创建 删除 重命名等等操作File累的对象最主要用来获取文件本省的一些信息 如文件所在的目录 文件长度 文件读写权限,数据流可以将数据写入文件中 文件也是数据流最常用的数据媒体
文件删除和创建
File类创建文件对象。通常有三种方法
第一种如下
File(String pathname)
//构造方法通过系该给定的路径名字符串为抽象路径名来创建一个新的File实例
new File(String pathname)
//其中,pathname代表路径名称
File flie =new File("D:\ps记录\ps 第二次作业");
//其中"D:\ps记录\ps 第二次作业"就是代表路径
第二种如下
File(String parent ,String child)
//该构造方法根据定义的父路径和子路径字符串(包括文件名)创建一个新的File对象
new File (String parent,String chile)
//new File(String parent ,String child)
//D:\ps记录\ps 第二次作业
parent: 父路径字符串 :ps记录
child:子路径字符串 :ps第二次作业
第三种如下
File (File f,String child)
//该构造方法根据f抽象路径名和child路径名字符串创建一个新的File实例
new File (File f,String child)
//f :父路径对象如 D:/doc/。
//child:子路径字符串,如letter.txt。
File类创建一个文件对象后 例如
File file=new File("D:\\word.txt");
例题:在D盘中创建文件如下
package 第十五章;
import java.io.File;
public class FileTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// \\一个斜杠的话就是要开始转义 俩个就是位置
// TODO 自动生成的方法存根
File file=new File("D:\\word.txt"); //创建文件对象
if(file.exists()) { //判断文件是否存在该如果不存在就跳到else循环
file.delete(); //将文件删除
System.out.println("文件已删除");
}else { //如果文件不存在
try { //try语句块捕捉可能出现的异常
file.createNewFile(); //创建该文件
System.out.print("文件已创建");
}catch(Exception e){
e.printStackTrace();
}
}
}
}
代码图
运行结果
文件已创建
15.2.2获取文件信息
File类提供了很多方法获取文件本身信息如下
方法 | 返回值 | 说明 |
getName() | String | 获取文件的名称 |
canRead() | boolean | 判断文件是否为可读的 |
canWrite() | boolean | 判断文件是否可被写入 |
exits() | boolean | 判断文件是否存在 |
length() | long | 获取文件的长度(以字节为单位) |
getAbsolutePath() | String | 获取文件的绝对路径 |
getParent() | String | 获取文件的父路径 |
isFile() | boolean | 判断抽象路径名表示的文件是否为一个标准 |
isDirectory() | boolean | 判断文件是否为一个目录 |
isHidden() | boolean | 判断文件是否为隐藏目录 |
lastModified() | long | 获取文件最后的修改时间 |
通过例题讲解 获取名称长度和隐藏属性
package 第十五章;
import java.io.File;
public class FileTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
File file=new File("D:\\word.txt"); //创建文件对象
if(file.exists()) { //如果文件存在
String name=file.getName(); //获取文件名称
long length=file.length(); //获取文件长度
boolean hidden=file.isHidden(); //判断文件是否为隐藏文件
System.out.println("文件名称:"+name); //输出信息
System.out.println("文件长度是:"+length);
System.out.println("该文件是隐藏文件吗?:"+length);
}else { //如果文件不存在
System.out.print("文件已创建"); //输出信息
}
}
}
代码图如下:
运行结果如下:
文件名称:word.txt
文件长度是:0
该文件是隐藏文件吗?:0
课堂内容:
代码如下
package 第十五章;
import java.io.File;
public class FileTest3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("D:\\ps记录\\ps 第二次作业");//获取路径
printAllFiles(file);
}
private static void printAllFiles(File file) {
File[]files = file.listFiles();//把路径内的数据 储存在File数组中
for (File f : files) {//for循环循环输出 File中的数据
if(f.isDirectory()) {//判断是否为文件 是的话就输出 不是的话就跳到else循环
System.out.println("-------- " + f.getName() +"--------------");
printAllFiles(f);
}else {
System.out.println(f.getName());
}
}
}
}
代码图如下:
运行结果如下:
一寸照蓝底.jpg
15.3文件输入/输出流
程序运行期间,大部分数据都在内存中进行操作,当程序结束或者关闭时,这些数据将消失,如果需要将数据永久保存, 就可以使用到输入输出流与指定的文件建立连接,当需要的数据永久保存到文件中就需要使用
FileInputStream类与FileOutputStream类都用来操作磁盘文件,其中FileInputStream是输入流 是将指定文件的内容来输入到程序中 这就是输入流 而FileOutputStream就是输出流 是将程序中的内容输出到指定的文件中 就是输出流 可能一开始说这些会比较难记 只会记得其中的两个同时按照顺序出现时 知道第一个是输入第二个是输出 我理解的是 两个不按照顺序出现的时候 其中有out的就是输出流 另外一个没有out的就是输入流 out是外的意思 就可以理解为是向外输出 这样的话就会比较好记一点 而如果这两个的意思不太清楚的话可以这么理解 输入流这个语句就是 文件在前程序在后 这就是输入流 相反程序在前输出在后的就是输出流 如以下代码所示
package 第十五章;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//字符字节流都是不能换行的 因为没有缓存的
//字节流FileInputStream输入 FileOutputStream输出
File file =new File("D:\\word.txt");//创造文件对象
FileOutputStream out = new FileOutputStream(file);//输出字节流 要输出到哪去 输出带file中
byte[] b1 = "hello world".getBytes();//使用getByte方法 将hello world传入到byte[]b1数组中
out.write(b1);//输出信息
out.close();//关闭流
FileInputStream in = new FileInputStream(file);//new对象 in 获取file位置获得文件中的内容 输入到程序中
byte [] b2 =new byte [1024];//创建一个byte数组来储存字节
int len =in.read(b2);//读取数组内的数据 int一个长度
System.out.print(new String(b2,0,len));//将b2转换为String类型 输出 重0开始到读取的长度
in.close();
}
}
代码图:
运行结果如下:
hello world
其中呢 分别是有输入流和输出流 先是写了一个输出流 向指定位置的文件中传入了 hello world 使用getByte方法 将 hello word传到数组中 然后使用write()来输出信息
再是输入流还是一样获取指定位置 然后使用数组来储存获取指定位置的内容 然后使用 int len =in.read(b2)来获取文件中的内容
运行结果中只有 hello world是因为输出是在文件夹中才能看到 输入流的话在控制台中就能够看到的
每次运行完都是要使用 close来关闭
15.3.2 FlieReader和 FileWriter类
上一小节讲的是FileInputStream类与FileOutputStream类这两个语句只能将输入输出字节 由于汉字在文件中占用两个字节 如果使用字节流读取不好的话可能会出现乱码现象 所以这一小节学习的是FlieReader和 FileWriter类可以避免这种现象 这个的使用方法跟上一小节的FileInputStream类与FileOutputStream类的内容十分相似 但是这些运行完关闭程序之后都会消失因为没有缓存功能所以我把本小节和 带缓存的输入输出流一起讲解
代码如下:
package 第十五章;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//字符字节流都是不能换行的 因为没有缓存的 如果需要缓存的话 就需要使用带缓存的字符流
// 字符路 FileReader输入流 FileWriter输出流
File file =new File("D:\\word.txt");//创造文件对象 获取文件位置储存到file中
FileWriter writer = new FileWriter(file);//输出字符流 要输出到哪去 输出file中
//char[] c1 = new char[]{'h','e','l','l','o'};//将char[]中的数据用c1储存
//带缓存的字符流 BufferedReader 输入 BufferedWriter输出
BufferedWriter bw = new BufferedWriter (writer);//需要先创建一个不带缓存的字符流 然后转换为带缓存的字符流 才能使用
bw.write("门前大桥下 游过一群鸭");//输出信息//可以跳过上一步 可以填到括号内 直接输出
bw.newLine();//创建一个新的行 达成换行的效果
bw.write("快来快来数一数 二四六七八");
bw.newLine();//创建一个新的行 达成换行的效果
bw.write("咕嘎咕嘎 真呀真多呀");
bw.newLine();//创建一个新的行 达成换行的效果
bw.write("数不清到底多少呀");
bw.close();//关闭带缓存流
writer.close();//关闭不带缓存流
//带缓存的字符流 BufferedReader 输入 BufferedWriter输出
FileReader reader = new FileReader(file);//new对象 in 获取file位置获得文件中的内容 输入到程序中
//char [] c2 =new char [1024];//创建一个char数组来储存字符
//int len =reader.read(c2);//读取数组内的数据 int一个长度
//System.out.print(new String(c2,0,len));//将b2转换为String类型 输出 重0开始到读取的长度
BufferedReader br = new BufferedReader(reader);//需要先创建一个不带缓存的字符流 然后转换为带缓存的字符流 才能使用
String s = br.readLine();//读取文件内的数据 传入到s中
System.out.println("第一行内容:"+s);//输出
System.out.println("第一行内容:"+br.readLine());
System.out.println("第一行内容:"+br.readLine());
System.out.println("第一行内容:"+br.readLine());
br.close();
reader.close();
}
}
代码图如下:
运行结果如下 :
第一行内容:门前大桥下 游过一群鸭
第一行内容:快来快来数一数 二四六七八
第一行内容:咕嘎咕嘎 真呀真多呀
第一行内容:数不清到底多少呀
本小节有点相同 其中不同的是上一小节用来储存的是byte[]数组 本小节的是char[]数组储存
然后再是调用write方法来将程序输出到指定文件中 输入流也是相同
然后再是带缓存的输入输出流 前提是需要先创建一个不带缓存的输入输出流 再转换为带缓存的输入输出流就好 输出可以像这种一样传入 这样子对于char数组来更方便一点
bw.write("门前大桥下 游过一群鸭");
这个带缓存的输入输出流 有一个不好的点就是不能换行 但是方法总比苦难多可以使用该方法
bw.newLine();//创建一个新的行 达成换行的效果
创建一个新的行 这样下一个就可以输入到新的行中 这样就可以达到换行的效果了
不管是带缓存的字符字节的输入输出流使用方法都是大差不差的 仔细看看就好了
15.5数据输入/输出
数据输入/输出()DataInputStream输入 DataOutputStream输出允许应用程序以与机器无关的方式从底层输入流中读取基本java数据类型 也就是说 当读取一个数据时,不必在关心这个数值因是哪个字节DataInputStream输入 DataOutputStream输出的构造方法和使用方法如下:
DataInputStream(InputStream in):使用指定的基础InputStream对象创建一个DataInputStream对象
DataOutputStream(OutputStream out)创建一个新的数据输出流,将数据写入指定基础输出流
这个数据输入输出好处是 可以指定输入输出指定的数据类 但是不好的地方也是 输出的东西输出到文件中是乱码 代码如下
package 第十五章;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class DatastreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file =new File ("D:\\word.txt");
//所有的数据流都是通过字节流转换过来的 先要有字节流 再有数据流
//DataInputStream输入 DataOutputStream输出
FileOutputStream fos=new FileOutputStream(file);
DataOutputStream dos=new DataOutputStream(fos);
dos.writeBoolean(false);//输出指定BOOLEAN类型的数据
dos.writeUTF("今天又在下雨");//向文件中输出char类型的数据
dos.writeFloat(2.58f);//向文件中输出Float类型的数据
dos.close();
fos.close();
//按什么顺序存进去的 就要按照什么顺序取出来 不然会出现没乱码
FileInputStream fis = new FileInputStream (file);//获取一个你想输入到程序内文件的位置
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readBoolean());//调用方法输出boolean方法
System.out.println(dis.readUTF());//调用utf来输出“今天又在下雨” 因为是没有read方法没有char 所以用另一种的utf
System.out.println(dis.readFloat());//输出Float
dis.close();//关闭流
fis.close();//关闭流
}
}
可以指定输入输出的类型 如下
dos.writeBoolean(false);//输出指定BOOLEAN类型的数据java
dos.writeUTF("今天又在下雨");//向文件中输出char类型的数据
dos.writeFloat(2.58f);//向文件中输出Float类型的数据
其中utf本来是char类型的 因为char类型中没有read方法 不能向文件中输出内容 所以换了另一种方法 就是UTF这样就可以输出 输出来类型
代码图:
输入结果内容:
false
今天又在下雨
2.58
输出到文件中的内容
浠婂ぉ鍙堝湪涓嬮洦@%?