JavaSE(十三)--File类和流

File类

1.File类

文件和目录路径名的抽象表示。

2.路径

绝对路径:带盘符的路径.
相对路径:相对某个文件或目录来描述的路径.
当相对的文件或目录与当前描述的文件或目录不在同一个盘符下时,绝对路径=相对路径.
在大部分情况情况下, 绝对路径!=相对路径.

3.file类常用方法:

public static void main(String[] args) {
		//创建一个文件对象
		//File f=new File("d:\\a.txt");
		File f=new File("d:"+File.separator+"a.txt");
		
		System.out.println("文件绝对路径:"+f.getAbsolutePath());
		System.out.println("文件相对路径:"+f.getPath());
		System.out.println("文件名:"+f.getName());
		System.out.println("文件是否可读:"+f.canRead());
		System.out.println("文件是否可写:"+f.canWrite());
		System.out.println("文件是否隐藏:"+f.isHidden());
		System.out.println("文件长度:"+f.length());
		long d1=f.lastModified();
		//将日期格式化
		String d2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d1);
		System.out.println("文件最后一次修改日期:"+d2);
	}

4.递归

方法自身调用自身.

  • 1:可以将原问题拆分成若干子问题,子问题的解决方法与原问题的解决方法一样.
  • 2:原问题的解决依赖于所有子问题的解决.
  • 3:递归一定要有出口.
/**
 * file类常用方法
 * (1)输出当前文件夹下所有以.txt结尾的子文件
 * (2)输出当前文件夹及后代文件夹中,所有以.txt结尾的子文件
 */
public class FileTest5 {

	public static void main(String[] args) throws IOException {
		//创建一个文件对象
		File f=new File("aa");
		if (f.isDirectory()) {//文件夹
			isDictory(f);
		} else {
			System.out.println("当前对象不是文件夹,无子文件");
		}
	
	}
	
	/**
	 * 判断当前文件夹下是否有以.txt结尾的文件,有就输出
	 */
	public static void isDictory(File f) {
		//获得当前文件夹下所有子文件和子目录
		File[] childFiles=f.listFiles();
		//遍历所有子文件和子目录
		for (File f2 : childFiles) {
			//判断当前遍历的对象是否是文件,且是否是以.txt结尾,输出
			if (f2.isFile()&&f2.getName().endsWith(".txt")) {
				System.out.println(f2.getPath());
			} else if(f2.isDirectory()){//当前对象是文件夹
				//递归,判断当前遍历的文件夹下面还有没有以.txt结尾文件
				isDictory(f2) ;
			}
		}
	}
}

5.过滤器

将需要数据留下来,不需要数据过滤掉.

public static void main(String[] args) throws IOException {
		//创建一个文件对象
		File f=new File("aa");
		//判断当前对象是否是文件夹
		if (f.isDirectory()) {
			//获得当前目录下以.txt结尾子文件,方法了匿名内部类过滤器对象
			String[] childFiles=f.list(new FilenameFilter() {
				@Override
				public boolean accept(File dir, String name) {
					//根据父目录对象和子文件名,创建子文件对象
					File  child=new File(dir, name);
					//判断当前的文件对象是否是文件,是否以.txt结尾
					if (child.isFile()&&name.endsWith(".txt")) {
						return true;
					}
					return false;
				}
			});
			
			for (String f2 : childFiles) {
				System.out.println(f2);
			}
			
		} else {
			System.out.println("当前的对象不是目录,没有子文件");
		}
	}

1.IO流

将数据从一个地方传输到另一个地方.

2.流的分类:

  • 1:按方向分:相对程序角度来说.
    输入流(读取流):将文件中数据读取到程序中.
    注意: 所有输入流,当文件不存在时,直接抛异常.
    输出流(写入流):将程序中数据写入到文件中.注意:所有输出流,当文件存在时,直接向文 件中写入数据;当文件不存在,先创建文件,再向文件中写入内容.

  • 2:按单位分:
    字节流:按字节为单位传输数据.作用:处理部分文本文件,图片,视频,二进制文件.
    字符流:按字符为单位传输数据.作用:处理所有文本文件.

  • 3:按功能分
    节点流:原始的流,没有封装任何其他流.
    处理流:封装节点流.

3.装饰者模式

封装原有类使其功能更强大.

4.基本字节流(原始字节流)

4.1:字节输入流

InputStream->FileInputStream

  • 1:一个字节一个字节的读取
public static void main(String[] args) throws IOException {
		//声明流对象
		InputStream is=null;
		try {
			//1.创建流对象
			is=new FileInputStream("aa"+File.separator+"a1.txt");
			/*2.用流对象一个字节一个字节的读取内容*/
			//先读取一次,返回就是读取的一个字节的Ansi码
			int content=is.read();
			while (content!=-1) {
				//将读取的内容输出
				System.out.println((char)content);
				//接着读取
				content=is.read();
			}
			System.out.println("读取完成!");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (is!=null) {
				is.close();
			}
		}
	}
  • 2:按字节数组的读取
public static void main(String[] args) throws IOException {
		//声明流对象
		InputStream is=null;
		try {
			//1.创建流对象
			is=new FileInputStream("aa"+File.separator+"a1.txt");
			/*2.用流对象一个字节一个字节的读取内容*/
			//准备一个字节数组读取
			byte[] b=new byte[10];
			//先按数组读取一次,读取的内容存在数组b中,返回读取的长度
			int len=is.read(b);
			while (len!=-1) {
				//将读取的内容输出
				System.out.println(new String(b, 0, len));
				//接着读取
				len=is.read(b);
			}
			System.out.println("读取完成!");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (is!=null) {
				is.close();
			}
		}
	}

4.2:字节输出流

OutputStream->FileOutputStream

public static void main(String[] args) throws IOException {
		//声明流对象
		FileOutputStream os=null;
		
		try {
			//1.创建流对象,先将文件中内容清空,再向文件中重写写入内容
			//os=new FileOutputStream("aa"+File.separator+"a1.txt");
			//加了第二个参数后,表示在原文件末尾追加数据
			os=new FileOutputStream("aa"+File.separator+"a1.txt",true);
			//2.用流对象向文件中写入内容
			os.write("Hello china".getBytes());
			os.write("我是中国人".getBytes());
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流,释放资源
			if (os!=null) {
				os.close();
			}
		}
	}

4.3:文件的拷贝

public static void main(String[] args) throws IOException {
		//声明流对象
		InputStream is=null;
		OutputStream os=null;
		try {
			//1.创建流对象
			is=new FileInputStream("aa"+File.separator+"a1.txt");
			//复制后的文件要与原文件后缀名相同(文件类型相同),文件名可以不同
			os=new FileOutputStream("bb"+File.separator+"b1.txt");
			/*2.用流边读取边写入*/
			//准备一个数组
			byte[] b=new byte[20];
			//先读取一次,读取的内容存在数组中,返回读取的实际长度
			int len=is.read(b);
			while (len!=-1) {
				//每读取一次就要写入一次
				os.write(b, 0, len);
				//接着读取
				len=is.read(b);
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (is!=null) {
				is.close();
			}
			if (os!=null) {
				os.close();
			}
		}
	}

5.字节缓冲流

处理流封装原始字节流
image-20201202001953549

5.1:字节缓冲输入流

FilterInputStream->BufferedInputStream

public static void main(String[] args) throws IOException {
		//声明流对象
		FilterInputStream fis=null;
		try {
			//1.创建流对象
			fis=new BufferedInputStream(new FileInputStream("aa"+File.separator+"c.txt"));
			/*2.用流对象读取文件中数据*/
			//准备一个数组
			byte[] b=new byte[10];
			//读取一次,读取的内容存数组b中,返回读取实际长度
			int len=fis.read(b);
			while (len!=-1) {
				//读取一次就输入一次
				System.out.println(new String(b, 0, len));
				//接着读取
				len=fis.read(b);
			}
			
			System.out.println("读取成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关闭流
			if (fis!=null) {
				fis.close();
			}
		}
	}

5.2:字节缓冲输出流

FilterOutputStream->BufferedOutputStream

public static void main(String[] args) throws IOException {
		//声明流对象
		FilterOutputStream fos=null;
		try {
			//1.创建流对象
			fos=new BufferedOutputStream(new FileOutputStream("aa"+File.separator+"c.txt"));
			//2.用流对象向文件中写入数据
			fos.write("Hello".getBytes());
			fos.flush();
			fos.write("java".getBytes());
			fos.flush();
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关闭流
			if (fos!=null) {
				fos.close();
			}
		}
	}

image-20201202002121358
image-20201202002139481
image-20201202002224387

其他流

所有字符流都是处理流封装字节流.

6.基本字符流

设置编码,实现内容追加.

6.1:基本字符输入流

Reader->InputStreamReader

public static void main(String[] args) throws IOException {
		//声明流对象
		FilterOutputStream fos=null;
		try {
			//1.创建流对象
			fos=new BufferedOutputStream(new FileOutputStream("aa"+File.separator+"c.txt"));
			//2.用流对象向文件中写入数据
			fos.write("Hello".getBytes());
			fos.flush();
			fos.write("java".getBytes());
			fos.flush();
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关闭流
			if (fos!=null) {
				fos.close();
			}
		}
	}

6.2:基本字符输出流

Writer->OutputStreamWriter

public static void main(String[] args) throws IOException {
		//声明流对象
		Writer w=null;
		try {
			//1.创建流对象,可以实现内容追加,设置编码
			w=new OutputStreamWriter(new FileOutputStream("aa"+File.separator+"d.txt",true), "gbk");
			/*2.用流向文件中写入数据*/
			w.write("我是程序猿");
			w.append("我爱java");
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (w!=null) {
				w.close();
			}
		}
	}

7.字符流

FileReader,FileWriter,特点:使用方便,不能设置字符编码.

public static void main(String[] args) throws IOException {
		//声明流对象
		FileReader r=null;
		FileWriter w=null;
		
		try {
			//1.创建流对象
			r=new FileReader("aa"+File.separator+"a1.txt");
			w=new FileWriter("bb"+File.separator+"c2.txt");
			/*2.用流对象读取和写入*/
			//准备一个数组
			char[] c=new char[10];
			//先读取一次
			int len;
			while ((len=r.read(c))!=-1) {
				//读取一次就写入一次
				w.write(c, 0, len);
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (r!=null) {
				r.close();
			}
			if (w!=null) {
				w.close();
			}
		}
	}

8.字符缓冲流

如果一行一行的读取,那么写入时一定要有换行符,否则会出现线程阻塞.
注意: 所有记事本文件和word文件自带换行.

8.1:字符缓冲输出流

BufferedWriter

public static void main(String[] args) throws IOException {
		//声明流对象
		BufferedWriter w=null;
		
		try {
			//1.创建流对象
			w=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("aa"+File.separator+"e.txt",true), "utf-8"));
			/*2.用流向文件中写入数据*/
			w.write("不忘初心");
			w.flush();//刷新
			//换行
			w.newLine();
			//\n可以换行
			w.append("方得\n始终");
			
			w.flush();//刷新
			//换行
			//w.newLine();
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (w!=null) {
				w.close();
			}
		}
	}

8.2:字符缓冲输入流

BufferedReader

public static void main(String[] args) throws IOException {
		//声明流对象
		BufferedReader r=null;
		
		try {
			//1.创建流对象
			r=new BufferedReader(new InputStreamReader(new FileInputStream("aa"+File.separator+"e.txt"), "utf-8"));
			/*2.用流读取文件中数据*/
			String content;
			while ((content=r.readLine())!=null) {
				//输出读取内容
				System.out.println(content);
			}
			System.out.println("读取成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (r!=null) {
				r.close();
			}
		}
	}

9.对象流

用来程序间交换数据.

  • 1:序列化:将程序(内存)中对象存到磁盘的文件中,叫序列化.
    持久化:将内存中短暂存储的数据存长久存储的磁盘上叫持久化.
    反序列化:将磁盘上文件中对象读取到程序(内存)中,叫反序列化.
  • 2:对象输出流:ObjectOutputStream
    注意: 对象输出流向文件中写入对象的过程,其实就是序列化.
public static void main(String[] args) {
		//声明流对象
		ObjectInputStream ois=null;
		
		try {
			//1.创建流对象
			ois=new ObjectInputStream(new FileInputStream("aa"+File.separator+"a.txt"));
			/*2.用流读取文件中对象*/
			
			//读取字符串对象
			//结论一:读取方法的数据类型要与写入方法的数据类型一致
//			Object ob1= ois.readObject();
//			System.out.println("读取的内容为:"+ob1);
			
			//读取一个学生对象
//			Student ob2=(Student)ois.readObject();
//			System.out.println(ob2);
		
			//读取多个对象
			List<Student> stulist=(List<Student>) ois.readObject();
			for (Student stu : stulist) {
				System.out.println(stu);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (ois!=null) {
				try {
					ois.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
}		
  • 3:对象输入流:ObjectInputStream
    注意: 对象输入流将文件中数据读取到程序中过程,其实就反序列化.
public static void main(String[] args) {
		//声明流对象
		ObjectInputStream ois=null;
		
		try {
			//1.创建流对象
			ois=new ObjectInputStream(new FileInputStream("aa"+File.separator+"a.txt"));
			/*2.用流读取文件中对象*/
			
			//读取字符串对象
			//结论一:读取方法的数据类型要与写入方法的数据类型一致
//			Object ob1= ois.readObject();
//			System.out.println("读取的内容为:"+ob1);
			
			//读取一个学生对象
//			Student ob2=(Student)ois.readObject();
//			System.out.println(ob2);
		
			//读取多个对象
			List<Student> stulist=(List<Student>) ois.readObject();
			for (Student stu : stulist) {
				System.out.println(stu);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关流
			if (ois!=null) {
				try {
					ois.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		}
  • 4:对象输入流读取的方法与对象输出流写入的方法类型要一致,否则会报错EOFException.(write数据类型()和read数据类型()这两个方法的数据类型要一致)

  • 5:只有实现序列化接口java.io.Serializable接口的类的对象,才能(序列化)用对象输出流写入到文件中.

  • 6:版本号错误:
    local class incompatible:
    stream classdesc serialVersionUID = -1243946572963888417
    local class serialVersionUID = 3821573340049539149

    • 操作:先将学生类的一个对象进行序列化(用对象输出流存到文件中),再修改学生类,再将现在的学生类反序列化取数据,就报版本号错误.
    • 原因:学生类只实现序列化接口,但是没有因定化序列化版本号,这样学生类每修改一次就会重新产生一个新的序列化版本号,如果你用原来序列化版本号对应类的对象存的数据,用新的序列化版本号就取不出数 据.
    • 解决:给每个序列化类固定版本号.
  • 7:如果序列化类中属性不想实现序列化,就用static或transient来修饰就可以

  • 8:如果想用对象流存多个对象到文件中,可以先将多个对象存在集合中,再把集合存到 文件中.

10.打印流:

10.1:字节打印流的使用:

public static void main(String[] args){
		//声明流对象
		PrintStream ps=null;
		
		try {
			//1.创建流对象
			ps=new PrintStream("aa"+File.separator+"b.txt");
			//2.用流向文件中写入数据
			ps.append("abc");
			ps.print("good");
			ps.println("bye");
			ps.printf("%.2f", 0.23232323);
			ps.write("java".getBytes());
			System.out.println("写入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//3.关闭流
			if (ps!=null) {
				ps.close();
			}
		}
	}

10.2:输出重定向

给流重新定义一个方向,将原来输出到控制台的数据,重新定义一个方向后,输出到文件中.

  • 语法
System.setOut(PrintStream ps);
public static void main(String[] args) throws FileNotFoundException {
		//输出重定向
		System.setOut(new PrintStream("aa"+File.separator+"c.txt"));
		System.out.println("我是程序猿");
		System.out.println("我爱java");
	}

10.3:输入重定向

给流重新定义一个方向,将原来从控制台接收的数据,重新定义一个方向后,从文件中接收.

  • 语法:
System.setIn(InputStream in) 
public static void main(String[] args) throws FileNotFoundException {
		//输入重定向
		System.setIn(new FileInputStream("aa"+File.separator+"c.txt"));
		Scanner input=new Scanner(System.in);
		System.out.println("请输入字符串");
		String s1=input.next();
		String s2=input.next();
		System.out.println("接收数据为:"+s1);
		System.out.println("接收数据为:"+s2);
	}

11.Properties类

properties配置文件类,按key-value存取值

public static void main(String[] args) throws Exception {
		//创建Properties对象
		Properties p=new Properties();
		//用Properties对象调用方法加载配置文件
		p.load(new FileInputStream("aa"+File.separator+"jdbc.properties"));
		//获取配置文件中属性值
		System.out.println("用户名:"+p.get("username"));
		System.out.println("密码:"+p.get("password"));
		System.out.println("url:"+p.get("url"));

	}

12.装饰者模式:

作用:封装原有类,使其功能更强大.
要实现装饰者模式,注意以下几点内容:
a.装饰者类要实现真实类同样的接口 或继承同样父类.
b.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入)
c.装饰类对象在主类中接受请求,将请求发送给真实的对象(相当于已经将引用传递到了 装饰类的真实对象)
d.装饰者可以在传入真实对象后,增加一些附加功能(因为装饰对象和真实对象都有同样 的方法,装饰对象可 以添 加一定操作在调用真实对象的方法,或者先调用真对象的方法,再添加自己的方法)

个人笔记,思路,仅供参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值