Java之File与IO流

首先,来说一说File  文件类,顾名思义,这个类的作用,就是将 系统中存在的文件,变成Java的对象。

注:所有的输出流初始化时,后边可以追加,true和false 意思为是否追加,默认false 就会覆盖源文件,

例:FileOutputStream fos=new FileOutputStream(filename,true);

代码中说吧:

package day0817;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class Demo1 {
	public static void main(String[] args) throws IOException {
        //File的三种初始化方式
//		1.
//		File f=new File("/Users/songqi/Desktop/day15.txt");
		//2.
//		File f=new File("/Users/songqi/Desktop/", "day15.txt");
		//3.
		File f1=new File("..");
		File f=new File(f1, "day15.txt");
		//判断文件或者文件夹是否存在
		System.out.println(f.exists());
		//新建一个文件
		f.createNewFile();
		//获得文件的名称
		System.out.println(f.getName());
		//相对路径,如果是相对路径就是相对路径,如果是绝对路径,就是绝对路径
		//相对于项目或是文件夹 文件
		System.out.println(f.getPath());
		//绝对路径   完整的路径 
		System.out.println(f.getAbsolutePath());
		//父目录
		System.out.println(f.getParent());
		//文件是否可读
		System.out.println(f.canRead());
		//文件是否可写
		System.out.println(f.canWrite());
		//是否是文件
		System.out.println(f.isFile());
		//是否是目录
		System.out.println(f.isDirectory());
		//最后一次修改的时间
		System.out.println(f.lastModified());
		Date date=new Date(f.lastModified());
		System.out.println(date);
		//文件字节大小
		System.out.println(f.length());
//		System.out.println(f.delete());
	}

}

 File提供的过滤方法 ,可以简单处理输入的File

 

package day0817;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

public class Demo2 {
	public static void main(String[] args) {
		File f=new File("/Users/songqi/Desktop/day15");
		//是否存在
		System.out.println(f.exists());
		//是否是目录
		System.out.println(f.isDirectory());
		//获得当前目录下的子目录和文件的字符串形式
//		String [] all=f.list();
		//过滤
//		String []all=f.list(new FilenameFilter() {
//			
//			@Override
//			public boolean accept(File dir, String name) {
//				// TODO Auto-generated method stub
//				
//				return name.endsWith(".docx");
//			}
//		});
		String []all=f.list((d,name)->name.endsWith(".java"));
		for(String s:all)
		{
			System.out.println(s);
		}
		
		//获得的目录下的子目录和文件的File形式
//		File[] files=f.listFiles();
		//过滤
//		File[] files=f.listFiles(new FileFilter() {
//			
//			@Override
//			public boolean accept(File pathname) {
//				// TODO Auto-generated method stub
//				return pathname.getName().endsWith(".java");
//			}
//		});
		File [] files=f.listFiles(file->file.getName().endsWith(".java"));
		
		for(File file:files) {
			if(file.isDirectory()) {
				System.out.println(file.getPath());
			}else {
				System.out.println(file.getName());
			}
		}
		
		
		
		
	}
}

对于文件夹呢,也是File来作为对象,其实 File 也就是一个路径,不管你是文件,还是文件夹。

对于文件夹,除了之上的操作,还有以下使用:

package day0817;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

public class Demo2 {
	public static void main(String[] args) {
		File f=new File("/Users/songqi/Desktop/day15");
		//是否存在
		System.out.println(f.exists());
		//是否是目录
		System.out.println(f.isDirectory());
		//获得当前目录下的子目录和文件的字符串形式
//		String [] all=f.list();
		//过滤
//		String []all=f.list(new FilenameFilter() {
//			
//			@Override
//			public boolean accept(File dir, String name) {
//				// TODO Auto-generated method stub
//				
//				return name.endsWith(".docx");
//			}
//		});
		String []all=f.list((d,name)->name.endsWith(".java"));
		for(String s:all)
		{
			System.out.println(s);
		}
		
		//获得的目录下的子目录和文件的File形式
//		File[] files=f.listFiles();
		//过滤
//		File[] files=f.listFiles(new FileFilter() {
//			
//			@Override
//			public boolean accept(File pathname) {
//				// TODO Auto-generated method stub
//				return pathname.getName().endsWith(".java");
//			}
//		});
		File [] files=f.listFiles(file->file.getName().endsWith(".java"));
		
		for(File file:files) {
			if(file.isDirectory()) {
				System.out.println(file.getPath());
			}else {
				System.out.println(file.getName());
			}
		}
		
		
		
		
	}
}

下面试试,打印输出某个文件夹下所有文件的路径

思考一下,很有意思的题

 

 

 

文件和文件夹到此结束,下面开始正题,IO流:

 

  字节流和字符流的区别就是 :字节流是一次读一个字节,而字符流是一次读一个字符也就是一个char ,所以呢,读文本文件的话,当然是用字符流快了,而读二进制文件之类的字节流效率高,这点有选择性的。

  那什么是输入流,什么是输出流呢?输入流,就是往内存中读取,就是输入流,从内存往文件中输出,就是输出流。

 节点流意思就是和文件直接操作的流就叫节点流,处理流也可以叫包装流,举个栗子就是,平常的输入输出流是水管,那么包装流就是加了个水龙头,这个水龙头就是处理流,也就是包装流。

图中,即为节点流及其子类,Input即为输入流,Output即为输出流,FileinputStream 是文件输入流,用这个读文件,FileOutputStream是文件输出流,用这个流对文件进行写入。

FilterInputStream及其子类 FilterOutputStream及其子类都是包装类,ObjectInputStream和ObjectInputStream是对对象进行序列化和反序列化用到的流-对象输入输出流。

 

按照惯例,代码中说:

package day0817;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class Demo5 {
	//文件流,节点流
	public static void main(String[] args) throws IOException  {
		//1创建流对象
//		FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
		//2.创建流对象
		File f=new File("/Users/songqi/Desktop/day15.txt");
		FileInputStream fis=new FileInputStream(f);
		//读 每次读一个字节  到尾返回的是-1 如果读汉字  读两次的值才是汉字
		System.out.println((char)fis.read());
//		System.out.println((char)fis.read());
//		System.out.println((char)fis.read());
//		System.out.println((char)fis.read());
//		System.out.println((char)fis.read());
		int temp=0;
		while((temp=fis.read())!=-1) {
			System.out.println((char)(temp));
		}
		//关闭流,如果不关闭有些流有时候会写不进去 
		fis.close();
		}

}

其中的路径问题呢,我这的环境是mac,不区分大小写,但是如果创建两个文件夹只是大小写有区别的话,是不让创建的。

Windows 不知道行不行,但是养成好习惯,最好是区分大小写的写法。

 

包装流的Demo

package day0817;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Demo6 {
	public static void main(String[] args) throws IOException {
		//1创建流对象
//		FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
		//2.创建流对象
		File f=new File("/Users/songqi/Desktop/day15.txt");
		FileInputStream fis=new FileInputStream(f);
		//转换字符流
		InputStreamReader ir=new InputStreamReader(fis);
		int temp=0;
		while((temp=ir.read())!=-1) {
			System.out.print((char)(temp));
		}
		//关闭流
		fis.close();
		ir.close();
	}

}

花式读方法

package day0817;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo7 {
	public static void main(String[] args) throws IOException {
		//1创建流对象
//		FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/15.txt") ;
		//2.创建流对象
		File f=new File("/Users/songqi/Desktop/day15.txt");
		FileInputStream fis=new FileInputStream(f);
//		byte[] b=new byte[(int) f.length()];
		//流的大小  要在没读之前调用  否则不准确的   流有指针
		byte[] b=new byte[fis.available()];
		//把 独到的字节数组存到字节数组b中,返回读到的字节总数
//		fis.read(b);
		//(字节数组 ,字节数组的起始位置,存几个) mac 好像区别,很奇怪,Windows上会显示空格,而mac却不显示空格
		fis.read(b, 100, 2);
		String s=new String(b, "gbk");
		System.out.println(s);
		//关闭流
		fis.close();
	}

}

 

花式写方法

package day0817;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo8 {
	public static void main(String[] args) throws IOException {
		File f2=new File("/Users/songqi/Desktop/1.txt");
		//没有文件会在自动创建 但是没有父目录 会抛异常 ,如果是 false 或者默认 会覆盖 ,true  则追加
		FileOutputStream fos=new FileOutputStream(f2,true);
		String all="Hello你好啊";
		byte [] b=all.getBytes();
//		fos.write(b);
		//字节数组,起始位置,长度
		fos.write(b, 2, 2);
		fos.close();
	}

}

再来一个Demo

 

package day0817;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo9 {

	public static void main(String[] args) {
		File f2=new File("/Users/songqi/Desktop/1.txt");
		FileOutputStream fos=null;
		//没有文件会在自动创建 但是没有父目录 会抛异常 ,如果是 false 或者默认 会覆盖 ,true  则追加
		try {
			fos=new FileOutputStream(f2);
			byte []b="hello".getBytes();
			fos.write(b);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fos!=null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
	}

}

包装流之缓冲输入流,包装后效率会比较高

package day0820;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo1 {
	public static void main(String[] args) throws IOException {
//		File f=new File("/Users/songqi/Desktop/1.PNG");
		FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/1.PNG");
		FileOutputStream fos=new FileOutputStream("/Users/songqi/Desktop/2.PNG");
		//缓冲区大小 8192字节
		BufferedOutputStream bos=new BufferedOutputStream(fos);
		
		int temp=0;
		while((temp=fis.read())!=-1) {
			bos.write(temp);
//			System.out.print((char)temp);
		}
		//是读之前就能available 还是读之后呢?有没有这个问题?
//		byte[] b=new byte[fis.available()];
//		fis.read(b);
//		fos.write(b);
		bos.flush();
		fis.close();
		fos.close();
	}

}

 

package day0820;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class Demo3 {
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		//判断是否。.
//		if(sc.hasNextInt()) {
//			int num=sc.nextInt();
//		}else {
//			System.out.println("不是数字");
//		}
		
		FileInputStream fis=new FileInputStream("/Users/songqi/Desktop/1.txt");
		Scanner sc2=new Scanner(fis);
		String s=sc2.next();
		System.out.println(s);
		//这是比较有趣的一个地方,如果是next()会发现永远不会读进去,只有nextLine 可以,因为nextLine 它会在读到分隔符的时候,读取分隔符前边的并返回后边的字符串
		Scanner sc3=new Scanner("aa bb cc");
		System.out.println(sc3.next());
		s=sc3.nextLine();
		System.out.println(s);
	}

}

数据流:这也是包装流的一种,挺神奇的,看一下,有点类似类的序列化和反序列化

package day0820;

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 Demo4 {
	public static void main(String[] args) throws IOException {
		//数据流
//		DataOutputStream dos=new DataOutputStream(new FileOutputStream("/Users/songqi/Desktop/1.txt"));
		File f=new File("/Users/songqi/Desktop/1.txt");
		FileOutputStream fos=new FileOutputStream(f);
		DataOutputStream dos=new DataOutputStream(fos);
		int [] no= {11,22,33};
		String [] name= {"ww","qwew","qweqwe"};
		for(int i=0;i<no.length;i++) {
			dos.writeInt(i);
			dos.writeUTF(name[i]);
		}
		dos.close();
		fos.close();
		FileInputStream fis=new FileInputStream(f);
		DataInputStream dis=new DataInputStream(fis);
		for(int i=0;i<no.length;i++) {
            //这个读写顺序是必须一样的
			System.out.println(dis.readInt());
			System.out.println(dis.readUTF());
		}
		dis.close();
		fis.close();
		
	}

}

下面比较重要的,序列化和反序列化:

这个是做什么呢,就是序列化对象,将之存到文件中,反序列化,将之从文件中读出来。

废话少说,上demo:

package day0820;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//序列化与反序列化
//要实现 Serializable 接口,进去你会发现是个 接口,而且任何抽象方法都没有,其实作用就是标记,这个类可以序列化
class Student implements Serializable{
	
	/**
	 * 版本号,这个UID是什么呢,就是如果你先序列化一个对象到本地,如果你更改这个类,比如加了个属性,那么再读取就会出错,因为系统会自动生成UID 因为 类变化了就不一样了,所以就会报错,而你这样定义呢,就不会
	 */
	private static final long serialVersionUID = 1L;
	
	
	private int no;
	private String name;
	int age;
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}
public class Demo5 {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//序列化,把对象转换成字节序列 
		Student stu=new Student();
		File f=new File("/Users/songqi/Desktop/1.txt");
		stu.setName("sq");
		stu.setNo(1);
		//1.创建流对象
		FileOutputStream fos=new FileOutputStream(f);
		//包装流
		ObjectOutputStream oos=new ObjectOutputStream(fos);
		//2.写
		oos.writeObject(stu);
		oos.close();
		
		//反序列化
//		FileInputStream fis=new FileInputStream(f);
//		ObjectInputStream ois=new ObjectInputStream(fis);
//		Student stua=(Student)ois.readObject();
//		System.out.println(stua.getName()+","+stua.getNo());
//		System.out.println(stua.age);
//		ois.close();
//		
	}

}

PrintStream:这个类就是输出比较方便

package day0820;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class Demo6 {
	public static void main(String[] args) throws IOException {
		//把一个文件内容读出来,在控制台显示
		//读
		File f=new File("/Users/songqi/Desktop/1.txt");
		FileInputStream fis=new FileInputStream(f);
		byte []b =new byte[fis.available()];
		fis.read(b);
		fis.close();

		//写控制台
		PrintStream ps=new PrintStream(System.out);
		ps.println(new String(b));
		ps.close();
	}

}

下面说说字符流:

其实字符流跟字节流在名字上很相像,初学者不好区分,凡是什么什么Stream这就是 字节流    而结尾是Reader和Writer的是字符流。

不多说,上Demo

读:

package day0820;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

//字符流
public class Demo7 {

	public static void main(String[] args) throws IOException {
		//读
		//1.
		FileReader fr=new FileReader("/Users/songqi/Desktop/1.txt");
		//2.读
		int temp=0;
		while((temp=fr.read())!=-1) {
			
			System.out.println((char)temp);
		}
		
		fr.close();
	}
}

写:

package day0820;

import java.io.FileWriter;
import java.io.IOException;

public class Demo8 {

	public static void main(String[] args) throws IOException {
		//写 
		String s="eqweqwe大大所多";
		FileWriter fw=new FileWriter("/Users/songqi/Desktop/1.txt");
		fw.write(s);
		fw.close();
		
		
	}

}

 

 

综合的来一个:

package day0820;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo9 {
	public static void main(String[] args) throws IOException {
		FileReader fr=new FileReader("/Users/songqi/Desktop/1.txt");
		int temp=0;
		StringBuffer s=new StringBuffer();
		while((temp=fr.read())!=-1) {
			s.append((char)temp);
		}
		System.out.println(s);
		s.reverse();
		FileWriter fw=new FileWriter("/Users/songqi/Desktop/1.txt");
		System.out.println(s);
		fw.write(s.toString());
		fw.close();
		fr.close();
	}

}

字符缓冲流:

 

package day0820;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Demo11 {
	//缓冲流
	public static void main(String[] args) throws IOException {
		File f=new File("/Users/songqi/Desktop/1.txt");
		FileReader fr=new FileReader(f);
		BufferedReader br=new BufferedReader(fr);
		String s1=br.readLine();
		System.out.println(s1);
		String s2=br.readLine();
		System.out.println(s2);
		String s3=br.readLine();
		System.out.println(s3);
		String s4=br.readLine();
		System.out.println(s4);
	}

}

 

PrintWriter:

package day0820;

import java.io.FileNotFoundException;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo12 {
	public static void main(String[] args) throws IOException {
		//这点的true,flase  是刷新缓冲区 而不是是否追加
		PrintWriter pw=new PrintWriter("/Users/songqi/Desktop/1.txt");
		for(int i=1;i<=5;i++) {
			pw.println("第"+i+"个数字");
		}
		pw.close();
		
			}

}

 

 

最后再说一个 try(流)catch{异常处理}  这点是可以默认关流的,如果你不这样写,而且还不关流的话,文件不会有任何信息,试试:

package day0820;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;

public class Demo13 {
	public static void main(String[] args){
		
		try (PrintWriter pw = new PrintWriter("/Users/songqi/Desktop/1.txt")){
			Scanner sc=new Scanner(System.in);
			
			//BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			for(;;) {
				String s=sc.next();
				if(s.equals("q")) {
					break;
				}
				pw.println(s);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值