目标
- 文件与目录管理
- 流
- 文件读写(字节流 字符流)
- 对象序列化
文件与目录管理
前置任务
前置需要了解的知识
1、持久化-永久保存有两种方式
- 1、存数据库里 --关系型数据库--方便多表连接查询 连接数限制 高并发慢 jdbc
- 2、存文件 --没有关系 简单的数据 高并发 读写快
2、windows和linux下目录有什么不同
windows d:/java24/file \
linux:/root/java24
通用方式 "d:"+File.separator+"io"
目录操作
构造方法:File(String pathname)
判断目录或文件是否存在的方法:exists()
创建目录的方法:mkdir() 一次创建一级目录
mkdirs() 一次创建多级目录
@Test
public void test01(){
//目录或文件实例化
File path=new File("e:/java24/io");
//1、判断文件或目录是否存在
boolean result1=path.exists();//判断目录或者文件是否存在
System.out.println("目录是否存在"+result1);
if(result1){//3、如果存在,就打印目录已存在
System.out.println("目录已存在");
}else{//2、如果不存在,创建目录
//path.mkdir();
path.mkdirs();
}
}
文件操作
文件创建:
构造方法:File(File path,String filename)
File(String 完整路径)
新建文件: createNewFile()
createNewFile()+File(File path,String filename)示例
@Test
public void test02(){
//存放一些东西到指定目录下的指定文件里
//1、文件实例化 (path,filename)
File path=new File("d:/java24/io");//目录
String filename="text01.txt";
File f=new File(path,filename);
//2、首先判断目录path是否存在
//2-2如果目录不存在
if(!path.exists()){
System.out.println("目录不存在,开始创建目录");
//2-2-1先创建目录 注意:mkdir一次只能创建一个 mkdirs可以一次创建多级目录(目录及父目录)
//path.mkdir();
path.mkdirs();
}
System.out.println("目录肯定创建出来");
//-----目录一定存在
//2-1-1-1 目录已存在情况下,判断文件是否存在
if(f.exists()){ //如果文件存在 打印文件已存在
System.out.println("文件已存在,可以进行后续操作了");
}else{//如果文件不存在 就需要创建文件
try {
boolean result=f.createNewFile();
if(result){//result==true
System.out.println("文件创建成功");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//上面演示和目录和文件的创建过程,以下程序假定文件已经存在 d:/java24/text01.txt
//文件的属性
@Test
public void test04(){
//目录和文件都已经存在情况下,查看文件属性
//如果目录和文件都已经存在的存在下,我们可以用
File f=new File("d:/java24/text01.txt");
if(f.exists()){
//可以通过get方法获取一些属性
System.out.println("可读属性:"+f.canRead());
System.out.println("可写属性:"+f.canWrite());
System.out.println("文件路径:"+f.getPath());
System.out.println("文件名字:"+f.getName());
System.out.println("绝对路径:"+f.getAbsolutePath());
System.out.println("是否隐藏:"+f.isHidden());
System.out.println("文件大小"+f.length());
System.out.println("最后一次修改时间:"+f.lastModified());
}
}
getPath和getAbsolutePath区别
new File("")时,路径为空时,getPath返回空值,getAbsolutePath可以返回当前绝对路径
new File("d:/file/mydata") 路径不为空时,两者都返回路径名。
@Test
public void test02() throws IOException{
File path = new File("");
System.out.println("==>"+path.getPath());
String cur_path=path.getAbsolutePath();//FILE为空字符串时,可以获取当前路径;如果路径不是空串时,就返回真实路径
System.out.println(cur_path);
File file1=new File(cur_path,"b.txt");
if(!file1.exists()){
file1.createNewFile();
}
}
// 列出目录下的所有文件.listFiles
//d:/java24/text01.txt 02.txt
// 1kb=1024byte
@Test
public void test05() {
File path = new File("d:/java24");
if (path.exists()) {// 目录存在
// 列出目录下的所有文件
File[] files = path.listFiles();
// 循环打印各文件情况 用for循环
for (File f : files) {
// 可以通过get方法获取一些属性
System.out.println("可读属性:" + f.canRead());
System.out.println("可写属性:" + f.canWrite());
System.out.println("文件路径:" + f.getPath());
System.out.println("文件名字:" + f.getName());
System.out.println("绝对路径:" + f.getAbsolutePath());
System.out.println("是否隐藏:" + f.isHidden());
System.out.println("文件大小" + f.length());
System.out.println("最后一次修改时间:" + f.lastModified());
System.out.println("-----------------------------------------");
}
}
}
流
从流向上分:
输入流: 从文件---》内存或程序 (in.read )
输出流:从程序或内存-文件 (out.write)
按处理数据的单位不同
字节流(以字节形式byte[]读取的 音频视频word excel)
字符流(char String 文本类型文件)
按功能不同
节点流(直接跟文件交互的 低级流)
处理流(缓冲流 高级流)
高级流要用到低级流的功能
Java语言中,控制数据流的类都放在java.io包中
1、操作字符流
读字符类文件
注意:存文件时要用utf-8编码,否则与我们的工作区编码方式 不匹配,出现乱码
// 字符流(可以用文本编辑器打开,可以正常看的 )
@Test
public void test07() throws IOException {
//文本文件的编码方式改为utf-8
// BufferedReader(Reader in) Reader我们选的是FileReader--->FileReader(File
// file)
File file = new File("d:/java24/text01.txt");//3
FileReader fr = new FileReader(file);//2
// 理解为是一个工具类,他专门用来读文本文件内容
BufferedReader br = new BufferedReader(fr);//1
while(true) {//4
String str = br.readLine();// 一次读取一行文本
if (str != null) {
System.out.println(str);
} else {
break;
}
}
}
text01.txt的内容:
wang-qj王秋菊
wang-hz
yin-ss
控制台输出:
写字符类文件
//字符流写操作 step2 向文本文件里写入内容
@Test
public void test08() throws IOException {
//确认文件是utf-8编码
File file=new File("d:/java24/text02.txt");
FileWriter fileWriter=null;
//第一个参数是为是否append
BufferedWriter bw=null;
try {
fileWriter = new FileWriter(file,true);//第二个参数是表示是否向文件中追加内容
bw=new BufferedWriter(fileWriter);
bw.write("问:没声音吗1111111111");//写文本
bw.newLine();//换行
//bw.flush();//冲下去
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{//记着关闭流
//如果调用了关闭流的方法,就不用手动调bw.flush()
bw.close();
fileWriter.close();
}
}
//step3 文本文件copy
//从d:/java24/text01.txt每次读一行,写入到d:/java24/text02.txt
@Test
public void test09() throws IOException{
//从d:/java24/text01.txt读
//每读到一行,向d:/java24/text02.txt写入
//step1 初始化输入输出流
FileReader fr=null;
BufferedReader br=null;
FileWriter fw=null;
BufferedWriter bw=null;
try {
System.out.println("开始初始化输入输出流");
//初始化输入流
File inputFile=new File("d:/java24/text01.txt");
fr=new FileReader(inputFile);
br=new BufferedReader(fr);
//初始化输出流
fw=new FileWriter("d:/java24/text02.txt",true);
bw=new BufferedWriter(fw);
//step2 死循环从输入流(也就是text01.txt)一行一行读
while(true){
//一次读取一行
String content=br.readLine();
if(content!=null){//如果读到的内容不为null
System.out.println("读到了一行,开始写入");
bw.write(content);
bw.newLine();
}else{
System.out.println("拷贝完成");
break;
}
}
} catch (Exception e) {
// 打印异常
e.printStackTrace();
}finally{
//关闭流
bw.close();
fw.close();
br.close();
fr.close();
}
}
//字节流操作 mytest01.docx mytest02.docx
@Test
public void test10() throws IOException{
//高级字节流BufferedInputStream(BufferedOutpoutStream) 低节流FileInputStream (FileOutputStream )
//注意节流得按节读
//step1 初始化输入输出流
FileInputStream fis=null;
BufferedInputStream bis=null;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
try{
System.out.println("初始化输入输出流");
File input=new File("d:/java24/mytest01.docx");
//初始化低级输入流
fis=new FileInputStream(input);
//初始化高级输入流
bis=new BufferedInputStream(fis);
File output =new File("d:/java24/mytest02.docx");
//初始化低级输出流
fos=new FileOutputStream(output);
//初始化高级输入流
bos=new BufferedOutputStream(fos);
System.out.println("准备工作已完成,开始从输入流读取");
System.out.println("开始预估文件大小");
int length=bis.available();
System.out.println("文件大小为:"+length);
//新建一个同样大小的byte数组用于临时缓存读到
byte[] b=new byte[length];
//调用
int read_len=bis.read(b);//把读到的数据临时放到byte数组中,这个方法返回值为读取到的字节大小,如果读完,返回-1
System.out.println("读到的文件长度"+read_len);
//把byte数组里的东西存到mytest02.docx里
if(read_len!=-1){
System.out.println("将读到的内容写入到新的文件里");
bos.write(b, 0, read_len);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//从下向上关闭流
bos.close();
fos.close();
bis.close();
fis.close();
}
}
改善的写法:
//字节流拷贝
@Test
public void test07(){
//FileInputStream BufferedInputStream
//FileOutputStream BufferedOutputStream
File file=new File("E:" + File.separator + "java6" + File.separator + "filestudy", "01.png");
FileInputStream in=null;
BufferedInputStream bis=null;
File file2=new File("E:" + File.separator + "java6" + File.separator + "filestudy", "10.png");
FileOutputStream out=null;
BufferedOutputStream bos=null;
try {
in=new FileInputStream(file);
bis=new BufferedInputStream(in);
out = new FileOutputStream(file2);
bos=new BufferedOutputStream(out);
//读取到的字节的长度
int b;
//7936 1024....791 -1
//bis.read() 每次读取到的字节数
while((b=bis.read())!=-1){
//把b长度的字节写入到bos里
bos.write(b);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
bos.close();
out.close();
bis.close();
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
作业:1、练习上面的字符流和字节流拷贝
2、预习对象序列化和反序列化
对象的序列化和反序列化
step1 新建一个可序列化的对象
Dept.java
1)implements Serializable
2)自动生成一个id:
private static final long serialVersionUID = 5321630967988198440L;
public class Dept implements Serializable{
/**
* 为他指定一个id
*/
private static final long serialVersionUID = -6773472139020270906L;
//部门编号
private int deptNo;
//部门名称
private String dname;
//部门所在地
private String loc;
public int getDeptNo() {
return deptNo;
}
public void setDeptNo(int deptNo) {
this.deptNo = deptNo;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
step2 新建一个文本文件
d:/java24/dept01.txt
序列化程序
也是文件操作
序列化涉及的流
低级流:FileOutputStream FileInputStream
高级流:ObjectOutputStream ObjectInputStream
把对象写入到--->txt文件里,用到的是FileOutputStream ObjectOutputStream
ObjectOutputStream.writeObject(Object o)
样例代码
@Test
public void test01() throws IOException{
//ObjectOutputStream writeObject(Object obj)
//为ObjectOutputStream准备一个低级流 FileOutputStream
FileOutputStream fos=null;
//step1 实例化一个工具ObjectOutputStream
ObjectOutputStream oos=null;
try {
System.out.println("开始实例化输出流对象");
File file=new File("d:/java24/dept01.txt");
fos=new FileOutputStream(file);
oos=new ObjectOutputStream(fos);
System.out.println("实例化输出流对象结束");
//--把dept对象存到dept01.txt
//step 2 准备一个dept01对象
System.out.println("准备一个dept对象");
Dept dept10=new Dept();
dept10.setDeptNo(10);
dept10.setDname("部门10");
dept10.setLoc("沈阳");
//step 3把对象持久化到文件里
if(dept10!=null){
System.out.println("开始序列化对象");
oos.writeObject(dept10);
System.out.println("序列化对象结束");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
oos.close();
}
}
//对象反序列化其实是 txt-->Object 解密
//ObjectInputStream.readObject()
@Test
public void test02() throws IOException{
FileInputStream fis=null;
//step1 实例化一个工具ObjectInputStream
ObjectInputStream ois=null;
try {
System.out.println("开始准备工具类");
File file=new File("d:/java24/dept01.txt");
fis=new FileInputStream(file);
ois=new ObjectInputStream(fis);
System.out.println("开始反序列化对象");
Dept dept=(Dept) ois.readObject();
if(dept!=null){
System.out.println(dept.getDname());
}
} catch (Exception e) {
// TODO: handle exception
}finally{
ois.close();
}
}