JAVA中File和IO

File(文件夹/目录)

作用:操作文件本身,如名字遍历删除,如果需要操作文件中的内容,我们必须使用Io来完成

window一般用\分割文件 然后 但是java中用//这个或者\

操作File常见方法:

  • String getName():获取文件名称

  • String getPath():获取文件路径

  • String getAbsolutePath():获取绝对路径

    相对路径和绝对路径:

    假如一个学生是我们班级的,我们只需要说他的名字就好,但是要是其他班级的就需要说明,是哪个班级的谁谁谁

  • File getParentFile():获取上级目录文件

    当一直向上找的时候,找到根目录的时候,在点一次就会返回null

  • boolean exists():判断文件是否存在

  • boolean isFile() :是否是文件

  • boolean isDirectory():判断是否是目录

  • boolean delete() :删除文件

  • boolean mkdirs():创建当前目录和上级目录

  • File[] listFiles() :列出所有文件对象

    递归:调用自己的方法

    演示一个递归操作 ,遍历一个文件夹的所有文件(包括子文件)

    注意:使用递归操作的时候,一定要给自己的方法一个出口 ,在递归调用的时候就是使用方法

     package cn.wolfd._02_filesDir;
    
    import java.io.File;
    
    public class FileDemodir {
        public static void main(String[] args) {
        //需求 : 遍历当前文件夹的所有文件(包括所有的子文件)
            File file = new File("F:\\java学习资料\\预习资料\\基础班资料\\第四阶段-基础高级阶段\\04-IO\\day01\\笔记");
            listFiles(file);
        }
        public static void listFiles(File file){
            //判断当前传入地址是否是文件
            if (file.isDirectory()){
                //如果是 就列出所有文件的对象
                File[] files = file.listFiles();
                //判断文件中是否有元素 如果不为空 那么就将此file遍历
                //遍历之后对没有文件夹执行listFile判断 如果是一个文件夹就继续遍历
                //如果不是文件夹,就直接打印名字
                if (files!=null){
                    for (File file1 : files) {
                        listFiles(file1);
                    }
                }
                //最后才会打印出 最开始的文件夹名字
                System.out.println(file);
            }
        }
    }
    
    

字符集

Unicode 万国码

GBK家族一个汉字为两个字符集

UTF-8亚洲通用字符集 一个汉字三个字节,支持中文,建议在开发中使用

ISO–8859-410 老外服务器编码格式,常用

ASCLL和ISO-8859-1不能存中文会乱码

编码和解码

编码-将字符串转为一个byte[]数组(转为计算机能看懂的语言)

//编码操作:String -> byte[]
byte[] data = input.getBytes(“UTF-8”);

解码-将byte[]数组转为String (转为人能看懂得语言)

//解码操作:byte[] -> String

String ret = new String(data, “ISO-8859-1”);

乱码的原因—编码的字符集不一样

解决方案-将乱码转为二进制byte[] 然后我们再将二进制数组,转为我们想要的字符集就可以了

IO

io我们都是站在内存角度说的,所以说我们读取进来,就是input 就是输入道内存中 output就是输出从内存中输出出去

读进来,写出去-----

流的分类

节点流 基本流

包装流 功能更强大的节点流

输入流和输出流的参考点 只有内存 没有其他

  • read 将文件中数据读进来
  • write 将程序中的数据写道文件中

四大基本流

流向字节流(单位是字节)字符流(单位是文字符)
输入流InputStreamReader
输出流OutputStringWriter

IO操作模板

1:创建目标源对象
    一般都是创建一个文件对象
2:创建io流对象(一个文件和程序的连接渠道)
    这个就是字节流字符流的各种形式
3:具体的Io流操作
    read方法 将文件中的读取到程序中
    writer方法 将程序中写出道文件中
4:关闭资源(勿忘) 当使用完不关闭浪费资源,关闭之后也就不能使用流了
    流对象.close(); 用完关闭就好了

InputStream

属于Io包 一个抽象类 一堆儿子

常用方法

1:close() 正常关闭

2:read() 一次读取一个字节

3:read(byte[] buff) 读取多个字节

4:available()方法可以自动算读取多少个字节

int available1 = in.available();
byte[] buff = new byte[available1];
public static void main(String[] args) throws IOException {
        //从指定文件按照字节为单位将数组读取到程序中
        //1:只当操作的源文件
        File file = new File("files/src.txt");
        System.out.println(file.exists());
        //2:创建输入流对象
        FileInputStream in = new FileInputStream(file);
        //3.执行read方法完成读取操作 提前准备一下接受的
        byte[] buff = new byte[3];
        int available = 0;
        int len = 0; 
        //每次数组都是添加到buffer数组中,后面可能存在元素覆盖不完的问题
        while((len = in.read(buff))!=-1){
            //只转换到读取到的字节数 
            System.out.print(new String(buff,0,3));
        }
        //4关闭资源
        in.close();
    }

OutputStream

属于Io包 一个抽象类 一堆儿子

常用方法

1.close(); 正常关闭

2:finalize()清理文件的连接,并且保证没有更多的引用流时,将调用此文件输出流的close方法

3:getChannel() 返回与此文件输出流相关练习的唯一FileChannel对象

4:write();写出一个字节

5:write(byte[] buff);写出多个字节

6:write(byte[] buff,int off,int len);写出多个字节

public static void main(String[] args) throws IOException {
        //1确定一个目标文件
        File file = new File("files/dest.txt");
        //2:创建文件输出流对象
        // public FileOutputStream(File file, boolean append)
        //如果再构造器的boolean输入true此时就可以实现追加输出
        FileOutputStream os = new FileOutputStream(file,true);
        //3:执行write方法完成输出操作
        os.write(65);
        os.write(66);

        os.write(new byte[]{65,66,67,68,69,70,100});
        //直接输入字符串 再输出的时候直接转换为byte数组 直接写出
        os.write("wolfd".getBytes());
        //用中文的时候 就不要轻易用
        os.write("wolfd".getBytes(),0,2);
        //4:关闭资源
        os.close();
    }

Write

常用方法

1.close(); 正常关闭

2:write();写出一个字符

3:write(char[] buff);写出多个字符

4:write(char[] buff,int off,int len);写出多个字符

5:构造器(File ,boolean b) 当b为true的时候就不覆盖文件中内容

public static void main(String[] args) throws IOException {
        //1:确定目标文件的路径,2创建输出流对象
        FileWriter fileWriter = new FileWriter("files/dest.txt",true);
        //3:执行write方法完成写出的操作
        fileWriter.write(65);
        fileWriter.write("中立群塔千百,知乎,知乎,摆渡荷载");
        fileWriter.write(new char[]{'A','B','C','D','E'},0,2);
        //4关闭资源
        fileWriter.close();
    }

Reader

(char 默认为null 读取的时候给定一个范围)

常用方法

1:close() 正常关闭

2:read() 一次读取一个字符

3:read(char[] buff) 读取多个字符

4:read(cahr[] buff,int off,int len);

public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("files/dest.txt");
        //一次读取一个字符
        int c = reader.read();
     
        System.out.println((char)c);

        //一次读取多个字符
        char[] cuff = new char[3];
        int read = reader.read(cuff);
        System.out.println(new String(cuff));
        int len=0;
    //精髓代码区
        while ((len=reader.read(cuff))!=-1){
            System.out.print(new 				                String(cuff,0,len));
        }
        reader.close();
    }

总结:------字节流和字符流 就是单位不同,

开发中纯文本的通常用字符流更方便,如果有图片或视频我们必须使用字节流 ,使用字符流的时候可以使用带范围的构造器,

文件拷贝操作

我们上边学习了io的操作,接下来我们具体实战一下,完成以下文件拷贝的操作 以及正确的处理异常以及原因

1:正常拷贝文件的操作

private static void copy() throws Exception{
    //1:creat target file
    File src = new File("file/copy_before.txt");
    File dest = new File("file/copy_after.txt");
    //2:creat IO Object
    FileReader in = new FileRead(src);
    FileReader out = new Filewiter(dest);
    //3:具体的IO操作
    int len = -1;//记录以及读取了多个字符
	char[] buff = new char[1024];//每次可以读取1024个字符
	len = in.read(buff);//先读取一次
	while(len > 0) {
		//边读边写
		out.write(buff, 0, len);
		len = in.read(buff);//再继续读取
	}
	//4):关闭资源(勿忘)
	out.close();
	in.close();
}

上面的代码,采用抛出异常的方式进行编写,接下来我们演示在代码内进行处理

2:有异常处理的文件拷贝工作

private static void copy2() {
	//1):创建源或者目标对象
	File src = new File("file/copy_before.txt");
	File dest = new File("file/copy_after.txt");

	//把需要关闭的资源,声明在try之外
	FileReader in = null;
	FileWriter out = null;
	try {
		//可能出现异常的代码
		//2):创建IO流对象
		in = new FileReader(src);
		out = new FileWriter(dest);
		//3):具体的IO操作
		int len = -1;//记录以及读取了多个字符
		char[] buff = new char[1024];//每次可以读取1024个字符
		len = in.read(buff);//先读取一次
		while (len > 0) {
			out.write(buff, 0, len);
			len = in.read(buff);//再继续读取
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		//4):关闭资源(勿忘)
		try {
			if (out != null) {
				out.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			if (in != null) {
				in.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

第三种改良版本

private static void copy2() {
	//1):创建源或者目标对象
	File src = new File("file/copy_before.txt");
	File dest = new File("file/copy_after.txt");

	//把需要关闭的资源,声明在try之外
	
	try(
        //指定可以自动关闭资源的io
    FileReader in =in = new FileReader(src);
	FileWriter out = out = new FileWriter(dest);
    
    ) {
		//3):具体的IO操作
		int len = -1;//记录以及读取了多个字符
		char[] buff = new char[1024];//每次可以读取1024个字符
		len = in.read(buff);//先读取一次
		while (len > 0) {
			out.write(buff, 0, len);
			len = in.read(buff);//再继续读取
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
    //等全部执行完毕之后自动关闭
}

总结:

(1):ctrl + alt + t 可以选择代码被什么包围,可以用于快速处理异常

(2):如果规避空指针异常错误 判断当!=null这样就可以

(3):因为四大基本类型都实现了closeable接口 (实现了此接口然后在处理异常时候,可以自动关闭io但是要在try(这里面 定义需要关闭的资源对象,全部初始化){}catch(){})

缓冲流

作用:减少磁盘IO工作量,提高效率

原理:内置8192(字节/字符),其实就是数组,将我们需要的字节和字符缓存起来,等存满8192个字节在进行输出,此时问题来了,如果没满就不输入了吗,当然不是

输出条件一:当8192个字符都装满的情况下都装满了 输出条件二:当执行close的时候自动执行输出操作(刷新)

四个基本缓冲流

BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter

用法

private static void copy3() throws Exception {
	//1):创建源或者目标对象
	File src = new File("file/郭德纲-报菜名.mp3");
	File dest = new File("file/郭德纲-报菜名2.mp3");
	//2):创建IO流对象
	BufferedInputStream bis = 
new BufferedInputStream(new FileInputStream(src), 8192);
	BufferedOutputStream bos = 
new BufferedOutputStream(new FileOutputStream(dest), 8192);
	//3):具体的IO操作
	int len = -1;//记录以及读取了多个字符
	byte[] buff = new byte[1024];//每次可以读取1024个字符
	len = bis.read(buff);//先读取一次
	while (len > 0) {
		//边读边写
		bos.write(buff, 0, len);
		len = bis.read(buff);//再继续读取
	}
	//4):关闭资源(勿忘)
	bos.close();
	bis.close();
}

对象序列化

序列化作用:把java堆内存中的对象数据,通过某种关系把对象数据存储到磁盘上或者网络上

反序列化作用:把磁盘文件中的对象的数据或者把网络节点上的对象数据恢复成Java对象的过程。

如果要做序列化操作和反序列化操 必须实现Serializable接口,如果版本号不一致,那么就会反序列化失败

可以通过IO中的对象流来做序列化和反序列化操作。

  • ObjectOutputStream:通过writeObject方法做序列化操作的

  • ObjectInputStream:通过readObject方法做反序列化操作的

使用transient修饰的字段不会被序列化

class User implements Serializable {
	private String name;
	private transient String password;
	private int age;
	......//省略一万行代码
}


public class ObjectStreamDemo {
	public static void main(String[] args) throws Exception {
		String file = "file/obj.txt";
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
		User u = new User("Will", "1111", 17);
		out.writeObject(u);
		out.close();
		//--------------------------------------
		ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
		Object obj = in.readObject();
		in.close();
		System.out.println(obj);
	}
}

java.io.InvalidClassException 异常

版本号不一致 序列化的版本号发生了改变
对象的serialVersionUID被改变了
    
为了避免代码版本升级而造成反序列化因版本不兼容而失败的问题,在开发中我们可以故意在类中提供一个固定的serialVersionUID值。
    class User implements Serializable {
	private static final long serialVersionUID = 1L;
     //TODO
}
无论如何结构都不能改变类的结构

Scanner

作用:对文件做扫描可以对文件进行操作

常用方法:

判断文件中是否有下一行 hasNextLine()

如果文中没有下一行那么久跳出nextLine()

标准IO

标准的输入:通过键盘录入数据给程序

标准的输出:在屏幕上显示程序数据

在System类中有两个常量int和out分别就表示了标准流:

InputStream in	= System.in;
PrintStream out = System.out;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值