Java教程

java基础-io

本文主要是介绍java基础-io,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.名称分隔符

package cn.sxt.io;

import java.io.File;

/**
 * 名称分隔符
 * @author luona
 *
 */
public class PathDemo01 {

	public static void main(String[] args) {
	  String path ="D:\\code\\容器\\容器\\src\\cn\\sxt\\io\\IO.png";
	  System.out.println(File.separatorChar);
	  
	  path="D:/code/容器/容器/src/cn/sxt/io/IO.png";
	  System.out.println(path);

	}

}

2.构造器

利用File类的构造器,创建File对象

package cn.sxt.io;

import java.io.File;
import java.net.URL;

/**
 * 名称构造器
 * @author luona
 *
 */
public class FileDemo01 {

	public static void main(String[] args) {
		String path="D:/code/容器/容器/src/cn/sxt/io/IO.png";
		
		//1、构建File对象:直接构造路径
		File src =new File(path);
		System.out.println(src.length());
		
		
	    //2、构建File对象:通过父子构建
		src = new File("D:/code/容器/容器/src/cn/sxt/io/IO.png");
		System.out.println(src.length());
		
		src = new File("D:/code/容器/容器/src/cn/sxt/io","/IO.png");
		System.out.println(src.length());
		
		//4.构建File对象:通过File对象构建
		src = new File(new File("D:/code/容器/容器/src/cn/sxt"),"/io/IO.png");
		System.out.println(src.length());
		
	}

}

3.相对路径和绝对路径

4.io类总结

  • InputStream/OutputStream

    字节流的抽象类。

  • Reader/Writer

    字符流的抽象类。

  • FileInputStream/FileOutputStream

    节点流:以字节为单位直接操作“文件”。

  • ByteArrayInputStream/ByteArrayOutputStream

​ 节点流:以字节为单位直接操作“字节数组对象”。

  • ObjectInputStream/ObjectOutputStream

    处理流:以字节为单位直接操作“对象”。

  • DataInputStream/DataOutputStream

    处理流:以字节为单位直接操作“基本数据类型与字符串类型”。

  • FileReader/FileWriter

    节点流:以字符为单位直接操作“文本文件”(只能写文本文件)。

  • BufferedReader/BufferedWriter

​ 处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率。

  • BufferedInputStream/BufferedOutputStream

    处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写效率。

  • InputStreamReader/OutputStreamWriter

​ 处理流:将字节流对象转化为字符流对象。

  • PrintStream

​ 处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活。

5.流划分

  • 流向:

    输入流:从数据源到程序。

    输出流:从程序到数据源。

  • 数据单元:

    字节流:以字节为单位获取数据,用于数据源是二进制文件(如图片、影音等),命名上通常以Stream结尾。

    字符流:以字符为单位获取数据,用于数据源是文本文件,命名上通常以Reder或Writer结尾

  • 处理对象:

    节点流:直接从数据源或目的地读写数据,FileInputStream、FileReader、DataInputStream等。

    处理流:不直接连接到数据源或目的地,通过对其他流的处理来提高程序性能,如BufferedInputStream、BufferedReader等。处理流也叫包装类。

6.常用流对象

6.1 文件字节流

文件字节流可以处理所有文件,二进制文件(图片,影音)

  • FileInputStream文件字节输入流 :
package cn.sxt.io;

import java.io.FileInputStream;

public class FileStreamDemo {

	public static void main(String [] args) {
		//创建文件字节输入流对象
		FileInputStream file = null;
		
		try { 
			file=new FileInputStream("d:/a.png");
			int temp=0;
			while((temp=file.read())!= -1) {
				System.out.println(temp);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

package cn.sxt.io;

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

public class SecondDemo {
	public static void main(String [] args) {
		
		//创建流对象
		FileInputStream  fix=null;
				try {
						fix=new FileInputStream("d:/a.txt");
						//读取
						int temp=0;
				        StringBuffer sb=new StringBuffer();
						while((temp=fix.read())!=-1) {
							System.out.println(temp);
							sb.append((char)temp);
						}
						System.out.println(sb.toString());
				
				} catch (Exception e) {
				
					e.printStackTrace();
				}finally {
					try {
						fix.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
	}

}

  • FileOutputStream 文件字节输出流 :
package cn.sxt.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamDemo {

	public static void main(String [] args) {
		//创建文件字节输入流对象
		FileInputStream fis = null;
		//创建文件字节输出流对象
		FileOutputStream fos=null;
		
		
		try { 
			fis=new FileInputStream("d:/a.png");
			//指定输出文件位置
			fos=new FileOutputStream("d:/aa.png");
			
			int temp=0;
			while((temp=fis.read())!=0) {
				fos.write(temp);  //这个是将数据保存在内存当中
			}
			//将数据从内存放入磁盘
			fos.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				fis.close();
				fos.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

6.2 通过缓存区提高读写效率
  • 方法一:使用byte数组用来缓存读取的数据,然后指定数组大小,将读取到的数据放入数组。如果数组放不下,就执行循环代码的下一行代码,然后直至把读取的数据全部循环放入数组运送完毕,此次文件读取就结束了! 这样可以不用一个一个字节去读取,可以用一个容器(数组)来装数据,这样程序的运行效率也会提高。

    package cn.sxt.io;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    public class FileStreamDemo {
    
    	public static void main(String [] args) {
    		//创建文件字节输入流对象
    		FileInputStream fis = null;
    		//创建文件字节输出流对象
    		FileOutputStream fos=null;
    		
    		
    		try { 
    			fis=new FileInputStream("d:/a.png");
    			//指定输出文件位置
    			fos=new FileOutputStream("d:/aa.png");
    			
    			int temp=0;
    			//创建一个byte数组缓冲区,用来存放 ,数组长度必须是2的整数倍
    			byte [] b=new byte[1024];  
    			while((temp=fis.read(b))!=-1) {  
    //				fos.write(temp);  //这个是将数据保存在内存当中
    				fos.write(b,0,temp);
    				
    			}
    			//将数据从内存放入磁盘
    			fos.flush();
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				fis.close();
    				fos.close();
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    
  • 方法二:

    FileInputStream 类中的available方法是读取文件的预估大小值,然后把它作为数组大小。

package cn.sxt.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamDemo {

	public static void main(String [] args) {
		//创建文件字节输入流对象
		FileInputStream fis = null;
		//创建文件字节输出流对象
		FileOutputStream fos=null;
		
		
		try { 
			fis=new FileInputStream("d:/a.png");
			//指定输出文件位置
			fos=new FileOutputStream("d:/aa.png");
			
			int temp=0;
			//创建一个byte数组缓冲区,用来存放 ,数组长度必须是2的整数倍
			/*
			 * //方式一: byte [] b=new byte[1024]; while((temp=fis.read(b))!=-1) { //
			 * fos.write(temp); //这个是将数据保存在内存当中 fos.write(b,0,temp);
			 * 
			 * }
			 */
			
			//方式二:
			byte [] b=new byte[fis.available()];  
			
			fis.read(b);
			fos.write(b);
			//将数据从内存放入磁盘
			fos.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				fis.close();
				fos.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

总结:方式一它的占内存小,但是他的效率比方式二低;

方式二占内存大,但是它的效率高。因此在数据不大的情况下,推介使用方式二。

  • 方式三:通过字节缓冲流提高读写效率

    BufferedInputStream和BufferedOutputStream这两个是缓冲字节流,通过内部缓存数组来提高操作流的效率。

    package cn.sxt.io;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    public class FileStreamBuffer3Demo {
    	
    	public static void main(String [] args) {
    		
    		FileInputStream fis=null;
    		FileOutputStream fos=null;
    		BufferedInputStream bis=null;
    		BufferedOutputStream bos=null;
    		
    		
    		try {
                
                //创建一根流管子通道
    			fis=new FileInputStream("d:/a.png");
    			bis=new BufferedInputStream(fis);
    			fos=new FileOutputStream("d:/aa.png");
    			bos=new BufferedOutputStream(fos);
    		    //缓冲流中默认的byte数组长度是8192
    			//读取
    			int temp=0;
    			while((temp=bis.read())!=-1) {
    				bos.write(temp);
    			}
    			
    			bos.flush();
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			
    			try {
    				//关闭顺序:后开的先关闭
    
    				if(bis!=null) {
    					bis.close();
    				}
    				if(fis!=null) {
    					fis.close();
    				}
    				if(bos!=null) {
    					bos.close();
    				}
    				if(fos!=null) {
    					fos.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    
    }
    
    
6.3 定义文件拷贝工具类
package cn.sxt.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileCopyTools {
	public static void main(String [] args) {
		
		copy("d:/a.png","d:/abc.png");
	}
	
	public static void copy(String src,String des) {
		
		//文件字节输入流
		FileInputStream fis=null;
		//字节缓冲输入处理流
		BufferedInputStream bis=null;
		//文件字节输出流
		FileOutputStream fos=null;
		//字节缓冲输出处理流
		BufferedOutputStream bos=null;
		
		try {
			
			bis=new BufferedInputStream(new FileInputStream(src));
			bos=new BufferedOutputStream(new FileOutputStream(des));
			
			//读取文件
			int temp=0;
			while((temp=bis.read())!=-1) {
				bos.write(temp);
			}
			//加载到内存中
			bos.flush();
		}catch(Exception e) {
            e.printStackTrace();			
		}finally {
			
			try {
				//关闭
				if(bis!=null) {
					bis.close();
				}
				if(fis!=null) {
					fis.close();
				}
				if(bos!=null) {
					bos.close();
				}
				if(fos!=null) {
					fos.close();
				}
				
				
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
	}

}

6.4 文件字符流

文件字符流的操作单位是“字符”,读取出来的数据是unicode编码,需要用char进行强转才能变成我们能看懂的符号。

  • 文件字符输入流:FileReader
package cn.sxt.io;

import java.io.FileReader;

public class FileReaderDemo {
	
	public static void main(String [] args) {
		
		//定义文件字符输入流
		FileReader  frd=null;
		
		try {
			//创建文件字符输入流对象
			frd =new  FileReader("d:/a.txt");
			
			//读取数据
			int temp=0;
			while((temp=frd.read())!=-1) {
				System.out.println((char) temp);
			}
		}catch(Exception  e) {
			 e.printStackTrace();
		}finally {
			try {
				if(frd!=null) {
					frd.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

}

  • 文件字符输出流:FileWriter

所有的输入或输出节点都需要在括号里加路径,就像是目的地或数据源。

package cn.sxt.io;

import java.io.FileWriter;

public class FileWriterDemo {
	
	public static void main(String [] args) {
		//定义文件输入字符流
		FileWriter fw=null;
		FileWriter fw2=null;
		
		
		try {
			fw=new FileWriter("d:/cc.txt");   //如果这个文件不存在,程序会自动创建一个
			
			//写入数据
			fw.write("你好呀!\r\n");   //\r\n  是回车换行,一起使用生效,只在windows系统中有效
			fw.write("helloWorld!");
			//刷新
			fw.flush();
			
			fw2=new FileWriter("d:/cc.txt",true);   //这里的true表示append = true,意思是是否追加字符
			//写入数据
			fw2.write("hello,helloWorld!");   //如果fw和fw2操作同一个文件,然后它的构造函数默认是覆盖之前文件中的内容
		    //刷新
			fw2.flush();
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭流
			try {
				if(fw!=null) {
					fw.close();
				}
				if(fw2!=null) {
					fw2.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

}

  • 使用字符流实现文本文件的拷贝处理 (使用数组缓冲区,提高效率)

    package cn.sxt.io;
    
    import java.io.FileReader;
    import java.io.FileWriter;
    
    public class FileCopeTool {
    
    	public static void main(String [] args) {
    		
    		//定义文件字符输入、输出流
    		FileReader fr=null;
    		FileWriter fw=null;
    		
    		
    		try {
    			
    			//创建文件字符输入、输出流对象
    			fr=new FileReader("d:/cc.txt");
    			fw=new FileWriter("d:/dd.txt");
    			
    			//读取数据
    			//添加数组缓冲区
    			char [] buffer=new char[1024];  //这里只能自定义数组长度,2的整数幂
    			int temp=0;
    			while((temp=fr.read(buffer))!=-1) {
    				fw.write(buffer,0,temp);
    			}
    			//刷新
    			fw.flush();
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    		   try {
    			   //没有关闭顺序
    			   if(fr!=null) {
    				   fr.close();
    			   }  
    			   if(fw!=null) {
    				   fw.close();
    			   }
    		   }catch(Exception e) {
    			   e.printStackTrace();   
    		   }
    		}
    	}
    }
    
6.5 字符缓冲流

处理流是对节点流进行包装,然后使用处理流来读取文件。

字符输入流缓冲流:BufferedReader,以”行“为单位对数据进行读取。

字符输出流缓冲流:BufferedWriter

  • 字符输入缓冲流 : BufferedReader
package cn.sxt.io;

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferReaderDemo {

	public static void main(String [] args) {
		
	   //定义文件字符输入流
	   FileReader fr=null;
	   //定义文件字符输入流缓冲流
	   BufferedReader br=null;
	   
	   try {
		   fr=new FileReader("d:/cc.txt");
		   br=new BufferedReader(fr);   //处理流对节点流进行包装
		   
		   String temp=null;
		   while((temp=br.readLine())!=null) {
			   System.out.println(temp);
		   }
		   
	   }catch(Exception e) {
		   e.printStackTrace();
	   }finally {
		   try {
			   //关闭顺序,后打开的先关闭
			   if(br!=null) {
				   br.close();
			   }
			   if(fr!=null) {
				   fr.close();
			   }
			   
		   }catch(Exception e) {
			   e.printStackTrace();
		   }
	   }
	}
}

  • 字符输出缓冲流:BufferedWriter

    package cn.sxt.io;
    
    import java.io.FileWriter;
    import java.io.BufferedWriter;
    
    public class BufferWriterDemo {
    
    	public static void main(String [] args) {
    		
    		FileWriter fw=null;
    		BufferedWriter bw=null;
    		
    		try {
    			fw=new FileWriter("d:/dd.txt");
    			bw=new BufferedWriter(fw);
    			
    			bw.append("却充满阳光,疑是地上霜");
    			bw.newLine();
    			bw.append("感时花溅泪,和不鸟惊醒");
    			bw.flush();
    		
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				if(bw!=null) {
    					bw.close();
    				}
    				if(fw!=null) {
    					fw.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    
  • 通过字符缓冲流实现文本文件的拷贝

    package cn.sxt.io;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    
    public class FileCopyTool3 {
    
    	public static void main(String [] args) {
    		copy("d:/cc.txt","d:/ee.txt");
    	}
    	
    	public static void copy(String src,String des) {
    		
    	    //创建字符输出、输出流对象和输入、输出缓冲流对象
    		FileReader fr=null;
    		BufferedReader br=null;
    		FileWriter fw=null;
    		BufferedWriter bw=null;
    		
    		
    		try {
    			
    			//创建流对象
    			fr=new FileReader(src);
    			br=new BufferedReader(fr);
    			
    			fw=new FileWriter(des);
    			bw=new BufferedWriter(fw);
    			
    			String temp=null;
    			//读取数据
    			while((temp=br.readLine())!=null) {
    				bw.write(temp);
    				bw.newLine();  //换行处理
    			}
    			//刷新
    			bw.flush();
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				//按顺序关闭
    				if(bw!=null) {
    					bw.close();
    				}
    				if(fw!=null) {
    					br.close();
    				}
    				if(br!=null) {
    					br.close();
    				}
    				if(fr!=null) {
    					br.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    
  • 通过字符缓冲流为文件中的内容添加行号

package cn.sxt.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class LineNumberDemo {
	
	public static void main(String [] args) {
		BufferedReader br=null;
		BufferedWriter bw=null;
		
		try {
			br=new BufferedReader(new FileReader("d:/ee.txt"));
			bw=new BufferedWriter(new FileWriter("d:/gg.txt"));
			
			String temp="";   //数据
			int i=1;   //行号
		  
			//读取数据,写入数据
			while((temp=br.readLine())!=null) {
				bw.write(i+"."+temp);
				bw.newLine();
				i++;
			}
			
			//刷新
			bw.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(br!=null) {
					br.close();
				}
				if(bw!=null) {
					bw.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}

}
6.6 转换流

​ InputStreamReader / OutputStreamWriter 用来实现将字节流转换成字符流。,这两个也是处理流。

package cn.sxt.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class ConvertStream {
	
	public static void main(String [] args) {
      BufferedReader br=null;
      BufferedWriter bw=null;
		
		try {
			//InputStreamReader是将字节流转成字符流,再把它放到BufferedReader缓冲流中去处理
			br=new BufferedReader(new InputStreamReader(System.in));
			bw=new BufferedWriter(new OutputStreamWriter(System.out));
		
		while(true) {
            
			bw.write("请输入:");
			bw.flush();
			String input =br.readLine();
			if("exit".equals(input)) {
				break;
			}

			bw.write("你输入的是:"+input);
			bw.newLine();
			
//			System.out.println(input);
			
		}
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(bw!=null) {
					bw.close();
				}
				if(br!=null) {
					br.close();
				}
				
			}catch(Exception e) {
				e.printStackTrace();
			}	
	}
	}
}

6.7 字符输出流

在java的io流中专门提供了用于字符输出的流对象PrintWriter。该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可通过println();方法实现自动换行。PrintWriter是个节点流,作用在文件上,而处理流是作用在节点流上,对节点流进行处理。

package cn.sxt.io;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class LineNumberDemo3 {
	public static void main(String [] args) {
		
		BufferedReader br=null;
		PrintWriter pw = null;
		
		try {
			br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/a.txt")));
			pw=new PrintWriter("d:/u.txt");
			
			//读取数据
			String temp="";
			int i=1;
			
			while((temp=br.readLine())!=null) {
				pw.println(i+"."+temp);
				i++;
			}
			//pw.flush();  这个不需要刷新,因为PrintWriter对象自带刷新功能
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			
			try {
				if(br!=null) {
					br.close();
				}
				if(pw!=null) {
					pw.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}
6.8 字节数组流

ByteArrayInputStream 和 ByteArrayOutputStream 经常用在需要流和数组之间转化的情况。

  • 字节数组输入流

    FileInputStream是把文件当作数据源。ByteArrayInputStream则是把内存中的”字节数组对象“当做数据源。

package cn.sxt.io;

import java.io.ByteArrayInputStream;

public class ByteArrayInputDemo {
	
	public static void main(String [] args) {
		
		byte [] arr="abcdefghijklmn".getBytes();
	    ByteArrayInputStream bis=null;
		StringBuffer sb=new StringBuffer();
	    
		
		try {
			
			//读数据,该构造方法的参数是一个字节数组,这个字节数组就是数据源
			bis=new ByteArrayInputStream(arr);
			int temp=0;
			while((temp=bis.read())!=-1) {
				sb.append((char)temp);
			}
			System.out.println(sb);
			
		}finally {
			try {
			  	bis.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}
  • 字节数组输出流

    ByteArrayOutputStream 流对象是将流中的数据写入到字节数组中。

    package cn.sxt.io;
    
    import java.io.ByteArrayOutputStream;
    
    public class ByteArrayOutputDemo {
    
    	public static void main(String [] args) {
    		ByteArrayOutputStream bos=null;
    		
    		try {
    			bos=new ByteArrayOutputStream();
    			bos.write('a');
    			bos.write('b');
    			bos.write('c');
    			bos.write('d');
    			
    			StringBuffer sb=new StringBuffer();
    			
    			byte []  arry=bos.toByteArray();
    			for(int i=0;i<arry.length;i++) {
    				sb.append((char)arry[i]);
    			}
    			
    			System.out.println(sb.toString());
    			
    		}finally {
    			try {
    				if(bos!=null) {
    					bos.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
6.9 数据流

数据流将”基本数据类型与字符串类型“作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符类型。但不能对java对象进行读写操作(字符串除外)

DataInputStream 和 DataOutputStream 提供了可以存取与机器无关的所有Java基础类型数据(如:int、double、String等)的方法。它们是处理流,所以要通过节点流来指定操作文件所在位置。

  • 数据输出流:
package cn.sxt.io;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class DataOutputDemo {
	
	public static void main(String [] args) {
		DataOutputStream dos=null;
		
		try {
			dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/dos.txt")));
		    dos.writeChar('a');
		    dos.writeDouble(Math.random());
		    dos.writeUTF("数据流");
		    dos.writeBoolean(true);
		    dos.writeInt(2);
		    
		    dos.flush();
		}catch(Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(dos!=null) {
					dos.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}	
		}	
	}
}
  • 数据输入流:将文件中的内容输入到程序当中,文件中的内容是乱码,注意:在读取文件的过程中,数据类型数据的读取顺序要和文件中的数据类型顺序一致!否则就会报java.io.EOFException异常!

    package cn.sxt.io;
    
    import java.io.BufferedInputStream;
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    
    public class DataInputDemo {
    	public static void main(String [] args) {
    		DataInputStream dis=null;
    		
    		try {
    			dis=new DataInputStream(new BufferedInputStream(new FileInputStream("d:/dos.txt")));
               // 在读取文件的过程中,数据类型数据的读取顺序要和文件中的数据类型顺序一致!否则就会报java.io.EOFException异常!
    			System.out.println("char:"+dis.readChar());
    			System.out.println("double:"+dis.readDouble());
    			System.out.println("String :"+dis.readUTF());
    			System.out.println("Boolean:"+dis.readBoolean());
    			System.out.println("int:"+dis.readInt());
    					
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				dis.close();
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }
    
    
7.0 对象流

对象是用来存储数据的,但是它本身就是个数据,我们可以通过序列化和反序列化来将对象传输到硬盘的文件当中或者另一台电脑上进行保存.对象流中除了能实现对基本数据类型进行读写操作以外,还可以对java对象进行读写操作.

  • java对象的序列化和反序列化 :

    序列化 : 发送方把一个对象变成字节序列的过程 就叫序列化,然后丢给数据包,才能在网络上进行传输

    反序列化 : 接收方把字节序列变成一个对象的过程 就叫反序列化, 程序会去读取传过来数据包中的数据,然后恢复成一个对象,才能被正常读取

    对象的序列化 : 将java对象转换成字节序列的过程

    对象的反序列化 : 将字节序列恢复成java对象的过程

  • 序列化的作用:

    • 持久化: 把对象的字节序列永久地保存在硬盘上,通常存放在一个文件中
    • 网络通信: 在网络上传送对象的字节序列. 比如 : 服务器之间的数据通信,对象传递
  • 序列化所涉及的类和接口 :

    • ObjectOutputStream 代表对象输出流,它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中,它是处理流,需要套一个节点流来操作指定文件,关联数据源
    • ObjectInputStream 代表对象输入流,它的 readObject()方法从一个源输入流中读取字节序列,再把它们反序列化成一个对象,并将其放回,它是处理流,需要套一个节点流来操作指定文件,关联数据源
    • 只有实现了 Serializable 接口的类的对象才能被序列化, Serializable 接口是一个空接口,只起到标记作用
  • 写出基本数据类数据:

package cn.sxt.io;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamBasciTypeDemo {
	
	public static void main(String [] args) {
		ObjectOutputStream oos=null;
		
		try {
			oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("d:/oos.txt")));
			
			oos.writeInt(1);
			oos.writeDouble(Math.random());
			oos.writeChar('a');
			oos.writeUTF("oos");
			oos.writeBoolean(true);
			
			oos.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(oos!=null) {
					oos.close();
				}
			}catch(Exception e) {
					e.printStackTrace();
				}
			}
		
	}

}

  • 读取基本数据类型数据:

    注意,这个和数据流一样,读取时,需要和写入文件数据类型顺序一致,否则报错,不能正常读取

    package cn.sxt.io;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    public class ObjectInputStreamBasicTypeDemo {
    	public static void main(String [] args) {
    		ObjectInputStream ois=null;
    		
    		try {
    			ois=new ObjectInputStream(new BufferedInputStream(new FileInputStream("d:/oos.txt")));
    			//注意,这个和数据流一样,读取时,需要和写入文件数据类型顺序一致,否则报错,不能正常读取
    			/*
    			 * oos.writeInt(1); oos.writeDouble(Math.random()); oos.writeChar('a');
    			 * oos.writeUTF("oos"); oos.writeBoolean(true);
    			 */
    		    System.out.println("int :"+ois.readInt());
    		    System.out.println("double :"+ois.readDouble());
    		    System.out.println("char :"+ois.readChar());
    		    System.out.println("String: "+ois.readUTF());
    		    System.out.println("boolean: "+ois.readBoolean());
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				if(ois!=null) {
    					ois.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
  • 操作对象 :

    1.将对象序列化到文件:

    ObjectOutputStream 可以将一个内存中的java对象通过序列化的方式写入到磁盘的文件中.被序列化的对象必须要实现Serializable 序列化接口,否则会抛出异常

    第一步: 创建对象

    package cn.sxt.io;
    
    import java.io.Serializable;
    
    public class Users implements Serializable{
    	
    	private int userId;
    	private String userName;
    	private String userAge;
    	
    	public Users() {
    		
    	}
    	
    	public Users(int userId, String userName, String userAge) {
    		super();
    		this.userId = userId;
    		this.userName = userName;
    		this.userAge = userAge;
    	}
    
    	public int getUserId() {
    		return userId;
    	}
    
    	public void setUserId(int userId) {
    		this.userId = userId;
    	}
    
    	public String getUserName() {
    		return userName;
    	}
    
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    
    	public String getUserAge() {
    		return userAge;
    	}
    
    	public void setUserAge(String userAge) {
    		this.userAge = userAge;
    	}	
    }
    
    

第二步: 序列化对象

package cn.sxt.io;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamObjectTypeDemo {
	public static void main(String [] args) {
		ObjectOutputStream oos=null;
		
		try {
			oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("d:/object.txt")));
			Users user=new Users(1,"luona","20");
			oos.writeObject(user);
			oos.flush();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(oos!=null) {
					oos.close();
				}
				}catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

2.将对象反序列化到内存:

package cn.sxt.io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInputStreamObjectTypeDemo {
    public static void main(String [] args) {
    	ObjectInputStream ois=null;
    	
    	try {
    		ois=new ObjectInputStream(new  BufferedInputStream(new FileInputStream("d:/object.txt")));
    	    Users user=(Users)ois.readObject();
    	    System.out.println(user.getUserId()+"\t"+user.getUserName()+"\t"+user.getUserAge());
    	}catch(Exception e) {
    		e.printStackTrace();
    	}finally {
    		try {
    			if(ois !=null) {
    				ois.close();
    			}
    		}catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
}

7.1 随机访问流
  • RandomAccessFile 可以实现两个作用:

    1.实现对一个文件做读和写的操作。

    2.可以访问文件的任意位置。不像其他流只能按照先后顺序读取。

  • 三个核心方法:

    1.RandomAccessFile(String name,String mode) name 用来确定文件;mode 取 r(读)或 rw(可读写) ,通过 mode 可以确定流对文件的访问权限。

​ 2.seek(long a) 用来定位流对象读写文件的位置,a 确定读写位置距离文件开头的字节个数。

​ 3.getFilePointer() 获得流的当前读写位置。

  • 视频一:
package cn.sxt.io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandTest01 {
      public static void main(String [] args) throws IOException {
    	 test1();
      }
      
      public static void test2() throws IOException{
    	  RandomAccessFile raf=new RandomAccessFile(new File("src/cn/sxt/io/BufferReaderDemo.java"),"r");
    	  //随机读取
    	  raf.seek(2);
    	  //读取
    	  //3、操作(分段读取)
    	  byte[] flush = new byte[1024];  //缓冲容器
    	  int len = -1;  //接受长度
    	  while((len = raf.read(flush))!= -1) {
    		  System.out.println(new String(flush,0,len));
    	  }
    	  raf.close();
      }
      
      public static void test1() throws IOException{
    	  RandomAccessFile raf=new RandomAccessFile(new File("src/cn/sxt/io/BufferReaderDemo.java"),"r");
    	  
    	  int beginPos=2;
    	  int actualSize = 10;
    	  //随机读取
    	  raf.seek(beginPos);
    	  //读取
    	  //3、操作(分段读取)
    	  byte[] flush = new byte[1024];  //缓冲容器
    	  int len = -1;  //接受长度
    	  while((len = raf.read(flush))!= -1) {
    		 
    		  if(actualSize>len) { //获取本次读取的所有内容
    			  System.out.println(new String(flush,0,len));
    			  actualSize-=len;
    		  }else {
    			  System.out.println(new String(flush,0,actualSize));
    			  break;
    		  }
    	  }
    	  raf.close();
      }
}
  • 视频二:
package cn.sxt.io;

import java.io.RandomAccessFile;

public class RandomAccessFileDemo {
	public static void main(String [] args) {
		
		RandomAccessFile raf=null;
		
		try {
			
			raf=new RandomAccessFile("d:/raf.txt","rw");
			
			//循环添加若干个数据
			int [] arr=new int[] {10,20,30,40,50,60,70,80,90,100};
			
			for(int i=0;i<arr.length;i++) {
				raf.writeInt(arr[i]);
			}
			
			raf.seek(0);  //指针所在位置,表示从0位置开始读取数据
			System.out.println(raf.readInt());  //由于int是4个字节,10和20都是4个字节,所以控制台会输出数字“10”.
			
			//每隔一个读取一个数
			for(int i=0;i<arr.length;i+=2) {
				raf.seek(i*4);
				System.out.print(raf.readInt()+"\t");
			}
			
			//插入一个数字
			raf.seek(8);
			raf.writeInt(45);
			
			System.out.println("插入后:");
			for(int i=0;i<arr.length;i+=2) {
				raf.seek(i*4);
				System.out.print(raf.readInt()+"\t");
			}
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(raf!=null) {
					raf.close();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}
7.2 打印流

第一种:

package cn.sxt.io;

import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintTest {
	
	public static void main(String [] args) throws FileNotFoundException {
		PrintStream ps = System.out;
		ps.println("打印流");
		ps.println(true);
		
		ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true);
		ps.println("打印流");
		ps.println(true);
		
		//重定向输出端
		System.setOut(ps);
		System.out.println("change");
		ps.close();
		
		//重定向回控制台
		System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));
        System.out.println("I am back");		
	}
}

第二种:

package cn.sxt.io;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;


public class PrintTest02 {
	
	public static void main(String [] args) throws FileNotFoundException {
		PrintWriter pw =new PrintWriter(new BufferedOutputStream(new FileOutputStream("d:/pw.txt")));
	    pw.println("打印流");
	    pw.println(true);
	    pw.close();
	}
}
7.3 File类在IO中的作用
  • 当以文件作为数据源或目标时,除了可以使用字符串作为文件以及位置的指定以外,也可以使用 File 类指定。

    package cn.sxt.io;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    
    public class FileInIODemo {
    
    	public static void main(String [] args) {
    		BufferedReader br=null;
    		BufferedWriter bw=null;
    		
    		try {
    			
    			//指定文件位置
    			br=new BufferedReader(new FileReader(new File("d:/print.txt")));
    			bw=new BufferedWriter(new FileWriter(new File("d:/file.txt")));
    			
    			//读取数据
    			String temp ="";
    			int i =1;
    			while((temp=br.readLine())!=null) {
    				bw.write(i+"."+temp);
    				i++;
    			}
    			//从内存刷新到磁盘中
    			bw.flush();
    		    
    			
    		}catch(Exception e) {
    			e.printStackTrace();
    		}finally {
    			try {
    				if(br!=null) {
    					br.close();
    				}
    				if(bw!=null) {
    					bw.close();
    				}
    			}catch(Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

7.File类

7.1 File类作用

可以实现对文件和目录的创建、删除等功能。

7.2 File类的方法
  • 针对文件操作的方法:

    createNewFile() ///创建新文件

    delete() //直接从磁盘上删除

    exists() //查询磁盘中的文件是否存在

    getAbsolutePath() //获取绝对路径

    getPath() //获取相对路径

    getName() //获取文件名,先当与调用了一个toString()方法

    isFile() //判断是否是文件

    length() //查看文件中的字节数

    isHidden() //测试文件是否被这个抽象路径名是一个隐藏文件

package cn.sxt.io;

import java.io.File;
import java.io.IOException;

public class FileDemo {

	public static void main(String [] args) throws IOException {
		//创建File对象
		File file=new File("d:/aa.txt");
		
		System.out.println(file.createNewFile());
		System.out.println(file.exists());
		System.out.println(file.delete());
        //其它File类的文件操作方法使用类似,比较简单
	}
}

  • 针对目录操作的方法:

    exists() //查询目录是否存在

    isDirectory() //判断当前路径是否为目录

    mkdir() //创建目录

    getParentFile() //获取当前目录的父级目录

    list() //返回一个字符串数组,包含目录中的文件和目录的路径

    listFiles //返回一个File数组,表示用此抽象路径名表示的目录中的文件

package cn.sxt.io;

import java.io.File;

public class DirectoryDemo {

	public static void main(String [] args) {
		//创建File对象
		File file=new File("d:/b/c");
		
		//创建目录
		System.out.println(file.mkdirs());
		
		//创建目录
		File file2=new File("d:/");
		
		String [] arry=file2.list();
		for(String a:arry) {
			System.out.println(a);   //结果是所有d磁盘下的目录名字
		}
		
		File [] file3=file2.listFiles();
		for(File f:file3) {
			System.out.println(f);   //结果是显示所有d磁盘下目录的绝对路径
		}
	}
}

8.Apache IO 包

Apache IO 就是 Apache-commons 工具包,其中提供了 IOUtils/FileUtils ,可以让我们非常方便地对文件和目录进行操作。

8.1 下载commons-io 包
  • 地址:https://commons.apache.org/proper/commons-io/download_io.cgi
  • 将commons-io 包导入项目中,就可以使用里面的类了。
8.2 FileUtils 类的使用
  • 常用方法:

    cleanDirectory : 清空目录,但不删除目录。

    contentEquals :比较两个文件的内容是否相同。

    copyDirectory : 将一个目录内容拷贝另一个目录。可以通过FileFilter 过滤需要拷贝的文件。

    copyFile : 将一个文件拷贝到一个新地址。

    copyFileToDirectory : 将一个文件拷贝到某个目录下。

    copyInputStreamToFile : 将一个输入流中的内容拷贝到某个文件。

    deleteDirectory : 删除目录。

    deleteQuietly : 删除文件。

    listFiles : 列出指定目录下的所有文件。

    openInputSteam : 打开指定文件的输入流。

    readFileToString : 将文件内容作为字符串返回。

    readLines : 将文件内容按行返回到一个字符串数组中。

    size : 返回文件或目录的大小。

    write : 将字符串内容直接写到文件中。

    writeByteArrayToFile : 将字符数组内容写到文件中。

    writeLines : 将容器中的元素的 toString 方法返回的内容依次写入文件中。

    writeStringToFile : 将字符串内容写到文件中。

  • FileUtils 类使用一之readFileToString方法:

    package cn.sxt.io;
    import java.io.File;
    import java.io.IOException;
    
    import org.apache.commons.io.FileUtils;
    public class FileUtilsDemo1 {
    
    	public static void main(String [] args) throws IOException {
    		String content = FileUtils.readFileToString(new File("d:/print.txt"),"utf-8");
    		System.out.println("content: "+ content);
    	}
    }
    
  • FileUtils 类使用二之copyDirectory方法:

    接口是可以被new的,就是需要注意去实现它里面的一些方法。

    package org.apache.commons.io;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.IOException;
    
    public class FileUtilsDemo2 {
    
    	public static void main(String [] args) throws IOException {
    		FileUtils.copyDirectory(new File("d:/a"), new File("e:/a"), new FileFilter() {
    
    			@Override
    			public boolean accept(File pathname) {
    				if(pathname.isDirectory() || pathname.getName().endsWith("html")) {
    					return true;
    				}
    				return false;
    			}
    			
    		});
    	}
    }
    
8.3 IOUtils 类的使用
  • IOUtils 类中的方法大部分都是重载的,方法总结如下:

    buffer 方法 : 将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。

    closeQueitly 方法 : 关闭流。

    contentEquals 方法 : 比较两个流中的内容是否一致。

    copy 方法 : 将输入流中的内容拷贝到输出流中,并可以指定字符编码。

    copyLarge 方法 : 将输入流中的内容拷贝到输出流中,适合大于2G 内容的拷贝。

    linelterator 方法 : 返回可以迭代每一行内容的迭代器。

​ read 方法 : 将输入流中的部分内容读入到字节数组中。

​ readFully 方法 :将输入流中的所有内容读入到字节数组中。

​ readLine 方法 :读入输入流内容中的一行。

​ toBufferedInputStream , toBufferedReader : 将输入转为带缓存的输入流。

​ toByteArray , toCharArray : 将输入流的内容转为字节数组、字符数组。

​ toString : 将输入流或数组中的内容转化为字符串。

​ write 方法 : 向流里面写入内容。

​ writeLine 方法 : 向流里面写入一行内容。

  • IOUtils 类使用一之 toString 方法:

    package org.apache.commons.io;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    
    public class IOUtilsDemo {
    	public static void main(String [] args) throws FileNotFoundException, IOException {
    		String content = IOUtils.toString(new FileInputStream("d:/print.txt"),"utf-8");
    		System.out.println(content);
    		
    	}
    }
    
这篇关于java基础-io的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!