IO流回顾

InputStream:字节输入流
OutputStream:字节输出流
Reader:字符输入流
Writer:字符输出流
当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做节点流,外部包装这个流的叫做包装流(处理流),关闭时只需关闭最外层包装流就行。
所有的流都实现了Closeable接口,都是可关闭的,用完流之后一定要关闭资源;所有的输出流都实现了Flushable接口,输出流在最终输出之后,一定要记得flush()刷新一下,清空管道。
java.io包下需要掌握的流有16个:

	文件专属
		FileInputStream;
		FileOutputStream;
		FileReader;
		FileWriter;
   	转换流
   		InputStreamReader;
   		OutputStreamWriter;
   	缓冲流(有缓冲区)
   		BufferedInputStream;
    	BufferedOutputStream;
    	BufferedReader;
    	BufferedWriter;
    数据流(可以对文件操作不同的数据类型)
    	DataInputStream;
    	DataOutputStream;
	标准输出流(PrintStream(File file)  使用指定的文件创建一个新的打印流,而不需要自动换行, 与其他输出流不同, PrintStream从不抛出IOException)
		PrintStream;
    	PrintWriter;
    对象专属流:(序列化与反序列化)
     	ObjectInputStream;
    	ObjectOutputStream;

文件的各种方法

   public boolean exists();测试此抽象路径名表示的文件或目录是否存在。
   public boolean isFile();测试此抽象路径名表示的文件是否是一个标准文件。
   public boolean isDirectory();测试此抽象路径名表示的文件是否是一个目录。
   public boolean isHidden();测试此抽象路径名指定的文件是否是一个隐藏文件。
   public boolean isAbsolute();测试此抽象路径名是否为绝对路径名
   public String getName();返回由此抽象路径名表示的文件或目录的名称。该名称是路径名名称序列中的最后一个名称。如果路径名名称序列为空,则返回空字符串。
   public String getPath();将此抽象路径名转换为一个路径名字符串。
   public String getParent();返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
   public String getAbsolutePath();返回此抽象路径名的绝对路径名字符串。
   public long lastModified();返回此抽象路径名表示的文件最后一次被修改的时间
创建文件
//File(String pathname)  通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
	File file = new File("C:\\715\\a.txt");
	//创建文件
	file.createNewFile();
		
	//File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例
	String parent = "C:\\715";
	String child = "b.txt";
	File file2 = new File(parent,child);

	//第3种
	File file3 = new File(parent,"c.txt");	
创建文件夹
//根据给定的路径名创建一个新的文件夹实例 
		File file = new File("c:\\715\\test");
		//判断该文件夹是否存在 
		System.out.println("test是否存在 " + file.exists());
		//创建文件夹
		file.mkdir();
		
		System.out.println("---------mkdir()与mkdirs()区别");
		File file2 = new File("c:\\715\\test2\\test3");
		//创建文件夹
		file2.mkdir();
		
		System.out.println("********************");
		
		System.out.println("---------mkdir()与mkdirs()区别");
		File file3 = new File("c:\\715\\test2\\test3");
		//创建文件夹
		file3.mkdirs();//能创建连续目录
删除文件或文件夹
//构造一个文件对象实例 
		File file = new File("c:\\715\\test");
		
		//删除test2目录 如果该路径下还有文件或文件夹,不能删除成功
		boolean result = file.delete();
		System.out.println("删除是否成功:" + result);
		
		//public void deleteOnExit();在虚拟机终止时,请求删除此抽象路径名表示的文件或目录
		//file.deleteOnExit();
获取文件列表
		File file = new File("D:\\");
				
		//获取所有文件路径
		File[] files = file.listFiles();
		for(File f:files) {
			System.out.println("文件:" + f);
		}
				
		System.out.println("*****************************");
				
		//获取文件名字符串
		String[] fs = file.list();
		for(String s:fs) {
		System.out.println(s);
		}
运用递归输出文件夹里所有文件
File file = new File("C:\\715\\io\\day1\\io");	
		//定义长度变量
		digui(file);

	}
	   //递归的层次不要太多,否则容易引起内存溢出
	private static void digui(File file) {
		//获取所有的文件
		File[] files = file.listFiles();
		//循环中判断
		for(File f:files) {	
			System.out.println(f.getName() + (f.isDirectory() ? "是文件夹": "是文件"))//判断
			if(f.isDirectory()) {
				//继续调用digui这个方法
				digui(f);
			}
		}
	}
对文件夹进行过滤
		//对文件夹内的文件进行过滤
        File file = new File("C:\\715\\io\\day1\\io\\src\\com\\gec\\file");

        //只需要.java文件
        // FilenameFilter:文件过滤器,需要重写方法
        File[] files = file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".java");
            }
        });
        
        for(File f:files) {
            System.out.println("文件名:" + f.getName());
        }
往记事本中写入数据

方法:
void close() 关闭此输出流并释放与此流相关联的任何系统资源。
void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。
void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
abstract void write(int b) 将指定的字节写入此输出流。

File file = new File("C:\\715\\b.txt");
				
//判断文件是否存在,不存在就创建
if(!file.exists()) {
	file.createNewFile();
}				
	OutputStream out = null;				
	try {
		//支持追加字符,默认是false
		out = new FileOutputStream(file,true);
		//调用写的方法
		/*
		out.write(97);
		out.write(98);
		out.write(99);
		 */
					
		byte[] b = new byte[] {97,98,99,100,101};
		out.write(b);
					
		String str = "你会找到一个比我更好的";
		out.write(str.getBytes());				
		System.out.println("写好了");
		} catch (Exception e) {
		e.printStackTrace();
	       }finally {
		if(out != null) {
			out.close();
		}
	}
利用文件通道读写文件
		//写
		File file = new File("c:\\715\\aa.txt");
		//利用通道
		try(FileOutputStream fos = new FileOutputStream(file)){
			//文件通道
			FileChannel fc = fos.getChannel();
			
			//定义容量
			ByteBuffer buff = ByteBuffer.allocate(1024);
			
			//定义一个数组
			byte[] b = new byte[] {65,66,67,68};
			//循环存储
			for(int i = 0;i < b.length;i++) {
				//存数据
				buff.put(b[i]);
			}			
			//反转(一定要反转)
			buff.flip();
			
			//把缓冲的数据写入通道
			fc.write(buff);
			
			System.out.println("ok");
		}
		//读
		File file = new File("c:\\715\\aa.txt");
		try(FileInputStream fis = new FileInputStream(file)){
			//获取文件通道
			FileChannel fc = fis.getChannel();
			
			//创建一个缓冲 
			ByteBuffer buff = ByteBuffer.allocate(1024);
			
			//从文件通道中取到的顺序字节,然后放到定义好的缓冲里面
			fc.read(buff);
			
			//反转
			buff.flip();
			
			while(buff.hasRemaining()) {
				byte b = buff.get();
				System.out.println((char)b);
			}
		}
读取当前文件内容并写到其他地方
File source = new File("C:\\715\\b.txt");
File target = new File("C:\\715\\T.txt");
				
//判断
if(!target.exists()) {
      target.createNewFile();
}
				
try(InputStream is = new FileInputStream(source);
	OutputStream out = new FileOutputStream(target);	
) {
   //定义一个缓冲数组					
	int hasread = 0;
	byte[] b = new byte[1024];
					
	while((hasread = is.read(b)) > 0) {
	//要把读取到的多少个字节(b)转换为String,长度是hasread
	out.write(b, 0, hasread);
}
} catch (Exception e) {
	e.printStackTrace();
}
使用缓冲流读取数据
 //不用再定义缓冲数组,自带缓冲
 FileReader source = new FileReader("D:\\715\\b.txt");
        FileInputStream fs = new FileInputStream("D:\\715\\b.txt");
        //转换流,将字节流转为字符流
        InputStreamReader is = new InputStreamReader(fs);
        
        BufferedReader br1 = new BufferedReader(is);
        BufferedReader br2 = new BufferedReader(source);
        String s = null;
        while ((s = br1.readLine())!=null){
            System.out.println(s);
        }
        while ((s = br2.readLine())!=null){
            System.out.println(s);
        }
        br1.close();
        br2.close();
使用缓冲流写数据
FileWriter fw = new FileWriter("D:\\715\\cc.txt",true);
        BufferedWriter out = new BufferedWriter(fw);
        out.write("债转股");
        out.write("\n");
        out.write("回复俄方");
        out.write(1213);
        out.flush();
        out.close();
字符输入流
//读取b.txt ,并打印到控制台
		File file = new File("C:\\715\\b.txt");
		
		//2字符输入流 读取字符用
		Reader r = new FileReader(file);
		
		//FileInputStream调用 read读取是一个字节
		//Reader read读取的是一个字符
            int hasread = 0;
		while((hasread = r.read()) >0) {
			System.out.print((char)hasread);//char强制转型成字符型
		}
		
		//关闭资源 
		r.close();
字符输出流
//跨平台写法 File.separator,相当于windows的\\和unix的/ 
		File file = new File("C:" + File.separator + "715" + File.separator + "c.txt");
		
		//判断文件是否存在
		if(!file.exists()) {
			file.createNewFile();
		}		
		//操作字符实例 
		Writer w = new FileWriter(file);
		//定义一个字符串
		String str = "天气这么热,我哪里也不想去,只想呆在房间写代码";		
		//调用方法写出去
		w.write(str);		
		System.out.println("写好了");		
		//关闭资源
		w.close();

文件拷贝

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。
BIO是一个连接一个线程。
NIO是一个请求一个线程。
AIO是一个有效请求一个线程。

BIO
public class test1 {
    public static void main(String[] args) throws IOException {
        File f3=new File("C:\\715");
        File f4=new File("D:\\715");
// 如果文件夹不存在就创建
        if (!f4.exists()) {
            f4.mkdirs();
        }
        kaobei(f3,f4);

    }
    private static void kaobei(File f3, File f4) throws IOException {
        //
        if(!f4.exists()) {
            f4.mkdirs();
        }
        //将文件遍历出来
        File[] f5=f3.listFiles();
        //循环
        for(File f:f5) {
            if(f.isDirectory()) {
                //创建文件实例
                File f6=new File(f3,f.getName());
                File f7=new File(f4,f.getName());
                //递归
                kaobei(f6,f7);
            }else {
                try(FileInputStream fi=new FileInputStream(f);
                    FileOutputStream fo=new FileOutputStream(f4+File.separator+f.getName())
                ){
                	//管道
                    FileChannel fc1=fi.getChannel();
                    FileChannel fc2=fo.getChannel();
                    fc1.transferTo(0, fc1.size(), fc2);
                }
            }
        }
        System.out.println("成功");
    }
}
AIO
public class test1 {
    public static void main(String[] args) throws IOException {
        File f3=new File("C:\\715");
        File f4=new File("D:\\715");
        //如果文件夹不存在就创建
        if (!f4.exists()) {
            f4.mkdirs();
        }
        kaobei(f3,f4);
    }
    private static void kaobei(File f3, File f4) throws IOException {
        //
        if (!f4.exists()) {
            f4.mkdirs();
        }
        //将文件遍历出来
        File[] f5 = f3.listFiles();
        //循环
        for (File f : f5) {
            if (f.isDirectory()) {
                //创建文件实例
                File f6 = new File(f3, f.getName());
                File f7 = new File(f4, f.getName());
                //递归
                kaobei(f6, f7);
            } else {
                try (InputStream fi = new FileInputStream(f);
                     OutputStream fo = new FileOutputStream(f4 + File.separator + f.getName())) {
					//BIO使用管道,AIO使用byte数组
                    int len = 0;
                    byte[] b = new byte[1024];
                    while ((len = fi.read(b)) > 0) {
                        fo.write(b, 0, len);
                    }
                }
            }
        }
    }
}
NIO
File source = new File("c:\\715\\io\\2.rar");
File target = new File("c:\\715\\3.rar");
		
long start = System.currentTimeMillis();
try(FileInputStream fis = new FileInputStream(source);
	FileOutputStream fos = new FileOutputStream(target)	
	){
			
	//获得各自的文件通道
	FileChannel fc = fis.getChannel();
	FileChannel fo = fos.getChannel();
			
	//0 表示索引的开始 ,fc.size:源文件的大小,fo:目标文件
	fc.transferTo(0, fc.size(), fo);
}

long end = System.currentTimeMillis();
//耗时:374毫秒
System.out.println("耗时:" + (end -start) + "毫秒");

序列化与反序列化

序列化:将java对象存储到文件中
反序列化:将硬盘上的数据恢复到内存当中,恢复成java对象
也可以序列化多个对象,把对象放入集合中

class Human implements Serializable{

	//一旦id生成,不要随便修改它!! 如果改了会发生 local class incompatible: 
	//stream classdesc serialVersionUID = 1, local class serialVersionUID = 1111
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Human(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Human [id=" + id + ", name=" + name + "]";
	}
}

public class TestPerson {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		File f = new File("C:\\715\\b.txt");
		try(OutputStream os = new FileOutputStream(f);
			ObjectOutputStream oos = new ObjectOutputStream(os)
			){
			Human h = new Human(1, "a");
			/**
			 * 把内存中的对象(new Human)固化到硬盘上(user.dat)
			 */
			oos.writeObject(h.toString()));
			oos.flush();
			oos.close();
			System.out.println("序列化对象完成");
		}
		//读取文件并反序列为内存中的对象
		try(
			InputStream is = new FileInputStream(f);
			ObjectInputStream ois = new ObjectInputStream(is)
			){
				Object obj = ois.readObject();
				System.out.println(obj);
				 ois.close();;
				System.out.println("反序列化对象完成");
			}
	}
}

IO和Properties联合使用

类似于这种机制的文件被称为配置文件,建议以.properties结尾

 FileReader fe = new FileReader("test01/src/userinfo.properties");

        //Properties是一个Map集合
        Properties po = new Properties();
        //将userinfo文件中的数据加载到Properties对象当中
        po.load(fe);
        //通过key来获取
        String username = po.getProperty("username");
        System.out.println(username);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值