文件复制及IO流笔记

File:对文件和文件夹的抽象

public class Demo01File {
    /*File:对文件和文件夹的抽象
     *属性:
     *  static String separator  :获取当前操作系统的路径分隔符
     *构造方法:
     *  File(File parent, String child) 
		File(String pathname) :参数指定file的路径
		File(String parent, String child)  
                    普通方法:
     *  boolean createNewFile() : 创建新文件  不能创建文件夹  
     *  boolean delete() : 删除文件/文件夹  删除文件夹时  文件夹必须为空
     *  boolean exists() :判断是否存在
     *  String getAbsolutePath()  :获取绝对路径
     *  String getName()  :获取文件夹/文件名字  不带目录
     *  String getPath()  :获取创建file对象时的构造方法的参数列表

     *  boolean isDirectory() :判断是否为目录: file必须存在
     *  boolean isFile()  :判断是否为文件: file必须存在
     *  long length()     :获取文件的字节个数:只能获取文件的字节个数
     *  File[] listFiles()  :获取当前文件夹下的所有直接子文件/文件夹
     *  
     *  boolean mkdir() :只能创建一层文件夹
     *  boolean mkdirs()  :创建多层文件夹
     *   
     *  boolean renameTo(File dest)  :重命名

     * */

file类的练习

//写一个方法遍历文件夹
public static void show(String fileName) {
    //获取file对象
    File file=new File(fileName);
    //判断是否存在
    if(!file.exists()) {
        throw new RuntimeException(fileName+"文件不存在");
    }
    //判断是文件还是文件夹
    if(file.isFile()) {
        System.out.println("文件:"+file.getAbsolutePath()+"::大小"+file.length()+"字节");
        return;
    }
    //文件夹
    System.out.println("文件夹:"+file.getAbsolutePath());
    //获取所有的直接子文件
    File[] zis=file.listFiles();
    for (File zi : zis) {
        //判断zi 是文件还是文件夹  是文件直接打印  是文件夹 继续获取所有的子文件/子文件夹
        //和当前方法的作用完全相同  使用递归
        show(zi.getAbsolutePath());
    }
}

IO流:计算机数据传输的抽象

public class Demo03IO {
    /*IO流:计算机数据传输的抽象
     * 流是一组有序的,有起点和重点的字节集合,是对计算机中数据传输的总称或者抽象 即数据在两个设备间的传输称为流,流的本质是数据传输。
     * 
     *IO流分类: i--in  o--out
     *按流传输方向分类: 参考对象是计算机内存
     *         输入流:把源文件中的信息读到内存中
     *              ---父类:InputStream/Reader
     *         输出流:把内存中的信息写到目的文件中
     *              ---父类:OutputStream/Writer
     *按流操作的基本单位分类:
     *         字节流:传输的基本单位是字节
     *               ----父类: InputStream/OutputStream
     *         字符流:传输时把同一个字符对应的多个之间作为整体来传输   
     *               ----父类:  Reader/Writer
     *按流关联的对象分类:
     *         节点流:创建流时关联的是文件对象---毛坯房
     *         过滤流/装饰流:创建流时关联的是其他流---精装房
     */
     

Stream 字节流

/*FileInputStream:字节输入流
     *     构造方法:
     *       FileInputStream(File file) 
             FileInputStream(String name) 
                                普通方法:    
     *      void close() :关闭流释放资源
     *      int read()   :每次读取一个字节    到达文件末尾返回-1
            int read(byte[] b)  
            *FileOutputStream:字节输出流        
     *     构造方法:
     *       FileOutputStream(File file) 
     *       FileOutputStream(String name) 
             FileOutputStream(File file, boolean append)
             FileOutputStream(String name, boolean append) 
                                普通方法:
             void close()  关闭流 释放资源
             void write(byte b) :一次写一个字节
             void write(byte[] b, int off, int len)  一次写一个字节数组的一部分 
             void write(byte[] b)  一次写一个字节数组
     * */
public class Demo01Stream {

	public static void main(String[] args)throws Exception {
		//实现文件的复制:把src/test/3.txt复制到4.txt中
		//FileInputStream+FileOutputStream
		//1 创建流与文件关联
		FileInputStream fin=new FileInputStream("src\\test\\3.txt");//相对路径:相对的是当前项目
		FileOutputStream fout=new FileOutputStream("src\\test\\5.txt",true);//fileoutputstream可以自动创建目的文件
		//FileOutputStreamd的第二个参数指定是否支持续写
		//2选择读写方式:逐个字节数组的读写
		long lon1=System.currentTimeMillis();

//		while(true){
//			//定义一个字节数组来记录读取的信息
//			byte[] arr=new byte[1024];
//			int n=fin.read(arr);//读取最多arr.length个字节 装入arr中  返回值是本次读取的有效字节数  如果到达文件末尾 返回-1
//			if(n==-1) {
//				break;
//			}
//			fout.write(arr, 0, n);//把arr的前n个有效字节写出去
//		}
		byte[] arr=new byte[1024];//定义一个数组装读取的字节信息
		int n;//定义一个变量记录每次读取的有效字节数
		while((n=fin.read(arr))!=-1){
			fout.write(arr, 0, n);
		}
		long lon2=System.currentTimeMillis();
		System.out.println(lon2-lon1);
		//3关闭流
		fin.close();
		fout.close();
	}

	private static void testStreamByByte() throws FileNotFoundException, IOException {
		//实现文件的复制:把src/test/3.txt复制到4.txt中
		//FileInputStream+FileOutputStream
		//1 创建流与文件关联
		FileInputStream fin=new FileInputStream("src\\test\\3.txt");//相对路径:相对的是当前项目
		FileOutputStream fout=new FileOutputStream("src\\test\\4.txt");
		//2选择读写方式:逐个字节的读写
		long lon1=System.currentTimeMillis();

//		while(true) {
//			int b=fin.read();
//			if(b==-1) {
//				break;
//			}
//			fout.write(b);
//		}
		int b;//定义一个变量记录每次读取的字节信息
	    while((b=fin.read())!=-1) {//1:fin.read()读取一个字节  2:b=fin.read()把读取的字节赋值给变量b 3:判断变量b是否等于-1 等于-1到达文件末尾
	    	fout.write(b);
	    }
		long lon2=System.currentTimeMillis();
		System.out.println(lon2-lon1);
		//3关闭流
		fin.close();
		fout.close();
	}

}

FileReader

public class Demo02FileReader {
    /*
     * FileReader:字符输入流  只能操作文本类型的文件
     * 构造方法:
     *    FileReader(File file) 
          FileReader(String fileName)  
                     普通方法:
     *    String getEncoding() :获取编码集
          int read()           :每次读取一个字符   如果到达文件末尾 返回-1
          int read(char[] cbuf) :读取最多cbuf.length个字符装入cbuf中 返回值是本次读取的有效字符数    如果到达文件末尾 返回-1
          void close()   :关闭流释放资源
          
      		FileWriter:字符输出流
                    构造方法:    
            FileWriter(File file) 
    		FileWriter(File file, boolean append) 
    		FileWriter(String fileName) 
    		FileWriter(String fileName, boolean append)  
                   普通方法:
             String getEncoding()  :获取编码集
             void close() :关闭流释放资源
    		 void write(int c) :一次写一个字符
    		 void write(char[] cbuf, int off, int len)  :一次写一个字符数组的一部分
    		 void write(String str, int off, int len) :一次写一个字符串的一部分
    		 void write(String str)  :一次写一个字符串
    		 void write(char[] cbuf) :一次写一个字符数组
    		 void flush()   :刷新  :处理fileoutputstream 其他输出流都要flush
    		 
     * */
    public static void main(String[] args)throws Exception {
    	//1 创建流与文件关联
    	FileWriter fout=new FileWriter("src\\test\\6.txt");
    	System.out.println(fout.getEncoding());
    	//2 选择写方式
    	fout.write(98);//一次写一个字符
    	fout.flush();
    	fout.write(38999);
    	fout.flush();
    	fout.write("\r\n");
    	fout.flush();
    	fout.write("你好吗?");//一次写一个字符串
    	fout.flush();
    	fout.write("\r\n");
    	fout.write("abcdefghijk", 2, 4);//一次写一个字符串的一部分
    	char[] arr="1234567890".toCharArray();
    	fout.write(arr);//一次写一个字符数组
    	fout.write("\r\n");
    	fout.write(arr,3,3);//一次写一个字符数组
    	//3关闭流释放资源
    	fout.close();
    	
    }
    
    private static void TestFileReader() throws FileNotFoundException, IOException {
    	//1 创建流与文件关联
    	FileReader fin=new FileReader("src\\test\\4.txt");

//		//2 选择读的方式:逐个字符
//		int b;
//		while((b=fin.read())!=-1) {
//			System.out.print((char)b);
//		}
		

		//2 选择读的方式:逐个字符数组
		char[] arr=new char[1024];
		int n;
		while((n=fin.read(arr))!=-1) {
			//把arr中读取的前n个有效字符写出去
			System.out.print(new String(arr, 0, n));
		}
		//3关闭流
		fin.close();
	}

}

转换流InputStreamReader、OutputStreamWriter


public class Demo03 {
    /*转换流:把字节流转换为字符流
     *   根据编码表把字节转换为字符
     *InputStreamReader:把字节输入流转换为字符输入流
     *OutputStreamWriter:把字节输出流转换为字符输出流
     *
     *OutputStreamWriter:
     * 构造方法:
     *     OutputStreamWriter(OutputStream out) 
           OutputStreamWriter(OutputStream out, String charsetName)  
                    普通方法:和FileWriter完全相同
          void close() 
          void flush() 
          String getEncoding() 
          void write(char[] cbuf, int off, int len) 
          void write(char[] cbuf) 
          void write(int c) 
          void write(String str, int off, int len)  
          void write(String str) 
          

     *InputStreamReader:
     *构造方法:
     *    InputStreamReader(InputStream in) 
          InputStreamReader(InputStream in, String charsetName) 
                 普通方法:和FileReader完全相同
     *     void close() 
           String getEncoding() 
           int read() 
           int read(char[] cbuf, int offset, int length) 
           int read(char[] cbuf)
     * */
    public static void main(String[] args)throws Exception {
    	//test01();
    	//把键盘输入的字符分类写到不同的文件中:数字一个文件 字母一个文件 其他一个文件
    	//方法一:通过scanner每次读取一个字符串  逐个字符判断 写入到不同的输出流中
    	//方法二:  逐个字符判断 写入到不同的输出流中
    	InputStream in=System.in;//获取系统输入流
    	InputStreamReader reader=new InputStreamReader(in);//写入到不同的输出流中
    	//创建三个输出流 分别与三个目的文件关联
    	FileOutputStream szStream=new FileOutputStream("src/test/数字.txt");
    	FileOutputStream zmStream=new FileOutputStream("src/test/字母.txt");
    	FileOutputStream qtStream=new FileOutputStream("src/test/其他.txt");
    	//把字节输出流转换为字符输出流
    	OutputStreamWriter sz=new OutputStreamWriter(szStream);
    	OutputStreamWriter zm=new OutputStreamWriter(zmStream);
    	OutputStreamWriter qt=new OutputStreamWriter(qtStream);
    	//选择读的方式:逐个字符数组的读写
    	int b;//定义变量记录每次读取的有效字节数
    	char[] arr=new char[10];//定义字符书序记录每次读取字节信息
    	while(true) {//系统输入流没有末尾
    		b=reader.read(arr);
    		String message=new String(arr, 0, b);//把读取的信息转换为字符串
    		for (int i=0;i<b;i++) {
    			char c=arr[i];
    			if(Character.isDigit(c)) {
    				sz.write(c); sz.flush();
    			}else if(Character.isUpperCase(c)||Character.isLowerCase(c)) {
    				zm.write(c);zm.flush();
    			}else {
    				qt.write(c);qt.flush();
    			}
    		}
    		if(message.indexOf("~")!=-1) {//定义一个结束的标志
    			break;
    		}
    		//System.out.println("message="+message);
    		//System.out.println(message.length());
    	}
    	//关闭流
    	qt.close();sz.close();zm.close();
    }
    
    private static void test01() throws IOException {
    	//把键盘输入的字符分类写到不同的文件中:数字一个文件 字母一个文件 其他一个文件
    	//方法一:通过scanner每次读取一个字符串  逐个字符判断 写入到不同的输出流中
    	//方法二:  逐个字符判断 写入到不同的输出流中
    	InputStream in=System.in;//获取系统输入流
    	InputStreamReader reader=new InputStreamReader(in);//写入到不同的输出流中
    	//创建三个输出流 分别与三个目的文件关联
    	FileWriter sz=new FileWriter("src/test/数字.txt");
    	FileWriter zm=new FileWriter("src/test/字母.txt");
    	FileWriter qt=new FileWriter("src/test/其他.txt");
    	//选择读的方式:逐个字符的读写
    	int b;//定义变量记录每次读取的信息
    	while((b=reader.read())!=-1) {
    		if(Character.isDigit(b)) {
    			sz.write(b); sz.flush();
    		}else if(Character.isUpperCase(b)||Character.isLowerCase(b)) {
    			zm.write(b);zm.flush();
    		}else {
    			qt.write(b);qt.flush();
    		}
    	}
    	//关闭流
    	qt.close();sz.close();zm.close();
    }

}

高效流(缓冲流) BufferedInputStream、 BufferedOutputStream

public class Demo04Buffered {
    /*
     * 高效流:输入装饰流;关联的是其他流
     *    特点:高效
     * 高效字节流:
     *    BufferedInputStream:   装饰流 对FileInputStream的封装:
     *                         除了效率更高  方法和FileInputStream完全相同
     *    BufferedOutputStream:   装饰流 对FileOutputStream的封装:
     *                         除了效率更高  方法和FileOutputStream完全相同
     *                         注意:BufferedOutputStream每读一次 需要flush一次
     *    
     * 高效字符流:
     *    BufferedReader: 对FileReader的封装
     *        方法和FileReader基本相同
     *           int read() 
			     int read(char[] cbuf, int off, int len) 
			     int read(char[] cbuf) 
			  特有方法:
			     String readLine():一次读取一行   读到null到达文件末尾

     *    BufferedWriter:对FileWriter的封装
     *        方法和FileWriter基本相同
     *            void close() 
                  void flush() 
                  void write(char[] cbuf, int off, int len) 
                  void write(char[] cbuf)
    			  void write(int c) 
    			  void write(String s, int off, int len) 
    			  void write(String s) 
                                        特有方法:
                  void newLine()  :写一个行分隔符:等价于write("\r\n")   
     * */
   

文件复制

 public static void main(String[] args)throws Exception {
    	//testBuffered1();
    	
    	//使用字符高效流实现文件复制
    	//1创建节点流与文件关联
    	//2创建高效流与节点流关联
    	BufferedReader bin=new BufferedReader(new FileReader("src\\test\\4.txt"));
    	BufferedWriter bout=new BufferedWriter(new FileWriter("src\\test\\8.txt"));
    	//3 选择读写方式:逐个字符  逐个字符数组 逐个字符串 逐行
    	String line;//定义引用记录本行读取的信息
    	while((line=bin.readLine())!=null) {//readLine()读取的信息中没有换行字符
    		bout.write(line);
    		bout.flush();
    		bout.newLine();
    		bout.flush();
    	}
    	//4 关闭流
    	bin.close();
    	bout.close();
    }
    
    private static void testBuffered1() throws FileNotFoundException, IOException {
    	//使用字节高效流实现文件复制
    	//1 创建节点流与文件关联
    	FileInputStream  fin=new FileInputStream("src\\test\\4.txt");
    	FileOutputStream fout=new FileOutputStream("src\\test\\7.txt");
    	//2 创建高效流与节点流关联
    	BufferedInputStream bin=new BufferedInputStream(fin);
    	BufferedOutputStream bout=new BufferedOutputStream(fout);
    	//3 选择读写方式:逐个字节读写 逐个字节数组读写
    	int n;
    	byte[] arr=new byte[1024];
    	while((n=bin.read(arr))!=-1) {
    		bout.write(arr, 0, n);
    		bout.flush();
    	}
    	//4 关闭流:只需要关闭装饰流即可
    	bin.close();
    	bout.close();
    }

}

文件/文件夹 复制

 public static void copy(File yuan,File muDiDir)throws Exception{
	       if(!muDiDir.exist()){
		        if(!muDiDir.mkdirs()){
				    throw new RuntimeException(muDiDir+"无法创建!");
				}
		   }
		   File muDi=new File(muDiDir,yuan.getName());
		   if(yuan.isFile()){
		       //创建文件
		       muDi.createNewFile();
			   //把yuan中的内容复制到muDi中
			   //创建流与文件关联
			   BufferedInputStream bin=new BufferedInputStream(new FileInputStream(yuan));
			   BufferedOutputStream bout=new BufferedOutputStream(new FileOutputStream(muDi));
			   //选择读写方式
			   byte[] arr=new byte[1024]; int b;
			   while((b=bin.read(arr))!=-1){
			       bout.write(arr,0,b);
				   bout.flush();
			   }
			   //关闭流
			   bin.close();bout.close();
               return;
		   }
		   //创建目的文件夹
		   muDi.mkdirs();
		   File[] zis=yuan.listFiles();
		   for(File zi:zis){
		       //把zi复制到muDi下
			   copy(zi,muDi);
		   }
	   }

PrintWriter:打印输出流

public class Demo05PrintWriter {
   /*
    * PrintWriter:打印输出流
    * 特点1: 所有流都是成对的  但打印输出流不是
    * 特点2:PrintWriter既可以是装饰流 也可以是节点流
    * 特点3:可以保证数据的原始格式
    * 
    * 
    * 特有方法:
    *    void print(boolean b) 
    * 其他方法和FileWriter完全相同    
    * */
   public static void main(String[] args)throws Exception {
	   PrintWriter pw=new PrintWriter("src/test/9.txt");
	   FileWriter  fw=new FileWriter("src/test/10.txt");
	   fw.write("舒适化123\r\n");
	   pw.write("舒适化123\r\n");
	   fw.write(true+"");
	   fw.write("\r\n");
	   pw.print(true);
	   pw.write("\r\n");
	   fw.write(98);//b
	   fw.write("\r\n");
	   pw.print(98);//98
	   pw.write("\r\n");//PrintWriter的print(n)等价于write(n+"")
	   pw.close();
	   fw.close();
   }
}

序列化流、反序列化流

public class Demo07ObjectStream {
  
    序列化流:把内存中对象的信息写到外部存储设备上
    反序列化流:把外部存储设备上的信息读到内存中重构成对象
    
    内存中对象的信息是字节形式存储
    序列化流和反序列化流实现---实现内存中的对象持久存储到硬盘上
    /*
    *ObjectInputStream:
    *     Object readObject()  
    *     ObjectInputStream(InputStream in) 
    *ObjectOutputStream:
    *     ObjectOutputStream(OutputStream out) 
    *     void writeObject(Object obj)  
    *
    *注意事项1: 序列化流和反序列化流的作用
    *     2:序列化和反序列化操作的对象的类必须实现序列化接口Serializable
    *     3:反序列化流ObjectInputStream的readObject方法读到文件末尾时 会抛出异常EOFException
    * 
    * 
    * 
    * */
	public static void main(String[] args)throws Exception {
    //		//java.io.NotSerializableException: com.zhiyou100.day15_thread.Student
            ArrayList<Student> list=new ArrayList<>();
    //		for (int i = 0; i <10; i++) {
    //			list.add(new Student((int)(Math.random()*10+10),Math.random()>0.5?'男':'女',"韩梅"+i));
    //		}
    //		//把这10个学生对象的内存信息持久化保持到硬盘中d:\\stu.obj
    //		//创建一个序列化流与目的文件关联
    //		ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream("d:\\stu.obj"));
    //		//选择写方式:逐个对象的写
    //		for (Student s : list) {
    //			oo.writeObject(s);
    //			oo.flush();
    //		}
    //		oo.close();
		

		//把硬盘中对象的信息读到内存中并重构成对象
		//创建反序列化流与源文件关联
		ObjectInputStream oi=new ObjectInputStream(new FileInputStream("d:\\stu.obj"));
		//选择读的方式:逐个对象的读取
		Object o;
		while(true) {
			try {
				o=oi.readObject();//到达文件末尾 抛出异常EOFException
			} catch (EOFException e) {
				break;
			}
			System.out.println(o);
			list.add((Student)o);
		}
		oi.close();
	
	}


}
class Student  implements Serializable{
	int age;
	char sex;
    protected String name;
	@Override
	public String toString() {
		return "Student [age=" + age + ", sex=" + sex + ",     name=" + name + "]";
	}
	public Student() {
	}
	public Student(int age, char sex, String name) {
		this.age = age;
		this.sex = sex;
		this.name = name;
	}
     
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值