IO流(3)

打印流

字节打印流

特有方法实现:数据原样写出。

java 复制代码
public class test {
    public static void main(String [] args) throws IOException, ClassNotFoundException  {
      //打印流
    	//创建字节打印流对象
    	PrintStream ps=new PrintStream(new FileOutputStream("c.txt"), true, "UTF-8");
    	ps.println(97);
    	ps.print(true);
    	ps.println();
    	ps.printf("%s喜欢%s","z","w");
    	ps.close();
    }
}

字符打印流

java 复制代码
public class test {
    public static void main(String [] args) throws IOException, ClassNotFoundException  {
      //打印流
    	//创建字符打印流
    	PrintWriter pw=new PrintWriter(new FileWriter("c.txt"), true);
    	pw.println("你好,java");
    	pw.close();
    }
}

压缩流与解压缩流

解压缩流

解压本质:把每一个zipEntry按层级拷贝到本地另一个文件夹中。

小练习:解压文件夹

将"D:\Date\aaa.zip"解压到"D:\Date"

java 复制代码
public class test {
    public static void main(String [] args) throws IOException   {
     //解压文件夹
    	File src=new File("D:\\Date\\aaa.zip");//原压缩文件夹地址
    	File dest=new File("D:\\Date");//目的文件夹地址
    	unzip(src, dest);
    }
    //创建一个解压方法对文件夹进行解压
    public static void unzip(File src,File dest) throws IOException {
    	//创建解压流对象:(读压缩流)
    	ZipInputStream zip=new ZipInputStream(new FileInputStream(src));
    	//利用while循环将文件夹中的每个对象解压出来,
    	ZipEntry entry;
    	while((entry=zip.getNextEntry())!=null) {
    		//有文件和文件夹
    		//对于文件和文件夹的处理方法不同,需要将二者分开处理
    		if(entry.isDirectory()) {
    			//文件夹
    			//需要将文件夹拷贝到指定地址,在目的地址创建一个相同的文件夹
    			File file=new File(dest, entry.toString());//因为entry为zip类型,所以需要转换成字符串
    			file.mkdirs();
    		}else {
    			//文件
    			//需要读取压缩包的文件,将其写到指定目的地址
    			FileOutputStream fo=new FileOutputStream(new File(dest,entry.toString()));
    			int b;
    			while((b=zip.read())!=-1) {
    				fo.write(b);
    			}
    			fo.close();
    			//关闭zip,证明一个文件已经处理完毕
    			zip.closeEntry();
    		}
    	}
    	zip.close();
    }

压缩流

压缩包里面的每一个文件或文件夹,看成一个ZipEntry对象。

压缩本质:把每一个文件或文件夹看成一个ZipEntry对象,放入到压缩包中。

练习1:压缩文件

将"D:\Date\c.txt"压缩到"D:\Date"

java 复制代码
public class test {
    public static void main(String [] args) throws IOException   {
    	 //压缩文件
    	File src=new File("D:\\Date\\c.txt");//要压缩的文件地址
    	File dest=new File("D:\\Date");//压缩包的文件地址
    	onZip(src, dest);
    }
    //创建一个压缩文件的方法
    public static void onZip(File src,File dest) throws IOException {

    	//创建一个压缩流来关联压缩包
    	ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(new File(dest,"c.zip")));//在根目录下创建一个zip的压缩包(一个壳子)
    	//创建ZipEntry对象,路径为压缩包里面的路径
    	ZipEntry entry=new ZipEntry("c.txt");
    	//把entry对象放到压缩包中
    	zos.putNextEntry(entry);
    	//将c.txt的内容写到压缩包中
    	FileInputStream fi=new FileInputStream(src);//读
     	int b;
     	while((b=fi.read())!=-1) {
		zos.write(b);
    	}
    	zos.closeEntry();
    	zos.close();
    }
}

练习2:压缩文件夹

将"aaa"文件夹压缩成一个"aaa.zip"压缩包

java 复制代码
public class test {
    public static void main(String [] args) throws IOException   {
    	//压缩文件夹
    	File src=new File("D:\\Date\\aaa");//文件夹的路径
    	//防止若改变了文件夹的路径,压缩包的路径找不到,所以将压缩包的路径拆开书写
    	//压缩包的父级路径
    	File parent=src.getParentFile();
    	//创建压缩包路径
    	File dest=new File(parent,src.getName()+".zip");
    	//创建压缩流关联压缩包
    	ZipOutputStream zos=new ZipOutputStream( new FileOutputStream(dest));
    	//获取src内的每一个文件,变成ZipEntry对象中,放入压缩包中
    	toZip(src, zos, src.getName());
    	zos.close();
    	
    }
    //原文件夹
    //压缩流
    //文件夹的名字,例如是src的aaa文件夹名
    public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {
    	//先遍历src获取每一个文件或文件夹
       File[] files=src.listFiles();
       for(File file:files) {
    	   //判断文件还是文件夹
    	   if(file.isFile()) {
    		   //文件
    		   //先将文件的路径写到ZipEntry对象中
    		   //file为为文件,file.getname是获取它的文件名为:dsr.txt
    		   //例如:要写入压缩包的路径为:\aaa\dsr.txt(文件夹下的文件)
    		   ZipEntry entry=new ZipEntry(name+"\\"+ file.getName());
    		   zos.putNextEntry(entry);
    		   //再获取file文件中的内容,写入到压缩包中
    		   FileInputStream fi=new FileInputStream(file);
    		   int b;
    		   while((b=fi.read())!=-1) {
    			   zos.write(b);
    		   }
    		   fi.close();
    		   zos.closeEntry();
    	   }else {
    		   //文件夹
    		   //递归调用方法
    		   toZip(file,zos,name+"\\"+file.getName());
    	   }
       }
    }
}

Commons-io(工具包)

Commons-io是一组有关IO操作的开源工具包。

作用:提高IO流的开发效率。

这是一个第三方工具类。

copyDirectory()------是将文件夹里的内容复制到另一个文件夹里。

copyDirectoryToDirectory()------是将第一个文件夹整体复制到另一个文件夹中。

java 复制代码
public class test1 {
    public static void main(String[] args) throws IOException {
        File src= new File("a.txt");
        File dest=new File("c.txt");
        FileUtils.copyFile(src,dest);

    }
}

都为静态方法之间调用使用。

Hutool(工具包)

IO的综合练习

练习1:制造假数据

需求:制造假数据也是开发中的一个能力,在各个网上爬取数据,是其中一个方法。

分析:先将各个网址定义出来,再定义一个方法进行网络爬取

只演示一个将姓氏爬取出来:

java 复制代码
public class test {
    public static void main(String [] args) throws IOException   {
    //https://www.threetong.com/qiming/baobao/27260.html 男生名字
    //https://www.threetong.com/qiming/baobao/27261.html 女生名字
    //https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d 百家姓
    	String firstname="https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d";
    	String boyname="https://www.threetong.com/qiming/baobao/27260.html";
    	String girlString="https://www.threetong.com/qiming/baobao/27261.html";
    	//定义一个方法进行爬取
    	String fn=copy(firstname);
    	String girl=copy(girlString);
    	String boy=copy(boyname);
    	//System.out.println(fn);
    	//定义一个正则表达式将需要的数据爬取出来
    	//定义一个方法
    	ArrayList<String> first=getDate(fn,"(\\W{4})(,|。)",1);
    	System.out.println(first);
    }
    private static ArrayList<String> getDate(String str,String regex,int index){//爬取的网址,正则表达式,
    	//将数据放在集合中,以便后续使用
    	ArrayList<String> list=new ArrayList<>();
    	//按正则表达式的规则获取数据
    	Pattern p=Pattern.compile(regex);//获取正则表达式
    	//到str中获取数据
         Matcher m=p.matcher(str);
         while (m.find()) {
        	 list.add(m.group(index));
         }
         return list;
    }
    
    public static String copy(String net) throws IOException {
    	//定义sb来拼接爬取到的数据
    	StringBuilder sb=new StringBuilder();
    	//创建一个URL对象
    	URL url=new URL(net);
    	//要链接这个网址
    	URLConnection con=url.openConnection();
    	//利用输入流来读取数据
    	//因为con方法调用只有字节输入流,所以需要将字节输入流包装成字符输入流,因为有文字需要爬取
    	InputStreamReader isr=new InputStreamReader(con.getInputStream());
    	int b;
    	while((b=isr.read())!=-1) {
    		sb.append((char)b);//将数据拼接到容器中
    	}
    	isr.close();
    	return sb.toString();
    }
}

练习2:带权重的随机点名器

txt文件中事先准备好10个学生姓名,每个学生的名字独占一行。

要求1:每次被点到的学生,再次被点到的概率在原先的基础上降低一半。

本题需要用到集合,I0,权重随机算法

分析:1)把文件的学生信息读到内存,放入集合中,集合为Student类型。

2)计算权重总和,利用遍历,再计算每一个的人实际占比,再计算每个人的权重占比范围

3)随机抽取,获取一个在0~1的随机数,获取随机数在数组的位置。

4)将这个元素的权重除2,再放回到集合中

5)再将修改了的值写入文件中

java 复制代码
public class Student {
	
	private String name;
	private String gender;
	private int age;
	private double weight;
	public Student() {
		
	}
	public Student(String name,String gender,int age,double weight) {
		this.name=name;
		this.gender=gender;
		this.age=age;
		this.weight=weight;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	@Override
	public String toString() {
		return name+"-"+gender+"-"+age+"-"+weight;
	}
	
}
java 复制代码
public class test {
    public static void main(String [] args) throws IOException {
    	//将文件的内容读取到内存
    	//然后放入集合中
    	ArrayList<Student>list=new ArrayList<>();
    	BufferedReader bf=new BufferedReader(new FileReader("n.txt"));
    	String len;
    	while((len=bf.readLine())!=null) {
    		String[] arr=len.split("-");
    		Student stu=new Student(arr[0],arr[1],Integer.parseInt(arr[2]),Double.parseDouble(arr[3]));
    		list.add(stu);
    	}
    	bf.close();
    	//计算权重总和
    	double weight=0;
    	for(Student s:list) {//遍历集合
    		weight+=s.getWeight();
    	}
    	//计算每一个人的权重占比,放入数组中
    	Double[] arr=new Double[list.size()];
    	int index=0;
    	for(Student stu:list) {
    		arr[index]=stu.getWeight()/weight;
    		index++;
    	}
    	//计算每个人权重占比范围
    	for(int i=1;i<arr.length;i++) {
    		arr[i]=arr[i]+arr[i-1];
    	}
    	 System.out.println(Arrays.toString(arr));
    	//获取一个随机数在0~1之间
    	  Double d= Math.random();
    	  System.out.println(d);
    	  //查找随机数在这个数组中的位置
    	  //利用二分查找
    	 int num= Arrays.binarySearch(arr, d);
    	 int result=-num-1;//将插入点转为正数
    	  Student s1= list.get(result);
    	  System.out.println(s1);
    	  //将这个元素的权重值要除2
    	 double w= s1.getWeight()/2;
    	 s1.setWeight(w);
    	 //将修改了的值再次写入到文件中
    	 BufferedWriter bw=new BufferedWriter(new FileWriter("n.txt"));
    	  for(Student s:list) {
    		  bw.write(s.toString());
    		  bw.newLine();
    	  }
    	  bw.close();
    }
}

练习3:登陆小案例(添加锁定账号功能)

将正确的用户名和密码手动保存在本地的文件中。格式为:username=zhangsan&password=123&count=0让用户键盘录入用户名和密码

比较用户录入的和正确的用户名密码是否一致

如果一致则打印登陆成功

如果不一致则打印登陆失败,连续输错三次被锁定。

java 复制代码
public class test {
    public static void main(String [] args) throws IOException {
    	//先读取文件
    	BufferedReader br=new BufferedReader(new FileReader("n.txt"));
    	String len=br.readLine();
    	br.close();
    	//将这个字符串分隔开
    	 String[] arr=len.split("&");
    	 String arr1=arr[0];//用户名
    	 String arr2=arr[1];//密码
    	 String arr3=arr[2];//次数
    	 //再将这三个分割
    	 String[] str1=arr1.split("=");
    	 String name=str1[1];//用户名
    	 
    	 String[] str2=arr2.split("=");
    	 String passwd=str2[1];//密码
    	 
    	 String[] str3=arr3.split("=");
    	 int count=Integer.parseInt(str3[1]);//次数
    	 //从键盘输入
    	 Scanner sc=new Scanner(System.in);
    	 while(true) {
    	 System.out.println("请输入用户名");
    	 String n=sc.nextLine();
    	 System.out.println("请输入密码");
    	 String number=sc.nextLine();
    	 
    	 //与用户比较
    	 if(n.equals(name)&&number.equals(passwd)&&count<=3) {
    		 //一致
    		 System.out.println("登录成功");
    		 break;
    		 
    	 }else {
    		 //不一致
    		 System.out.println("登录失败");
    		 count++;
    		 if(count<3) {
    			 System.out.println("登录失败,还剩"+(3-count)+"机会");
    		 }else {
    			 System.out.println("账户被锁定");
    			 break;
    		 }
    	 }
    	 write("username="+name+" "+"passwd="+passwd+" "+"count="+count);
    }
    }
  //要将count写入到文件中
	 public static void write(String str) throws IOException {
		 BufferedWriter bw=new BufferedWriter(new FileWriter("t.txt"));
		 bw.write(str);
		 bw.close();
	 }

	
}

将读n文件的信息,写入到t文件中。

相关推荐
drebander12 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天24915 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn21 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟22 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy31 分钟前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书33 分钟前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子35 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背35 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
bluefox197936 分钟前
使用 Oracle.DataAccess.Client 驱动 和 OleDB 调用Oracle 函数的区别
开发语言·c#
弗锐土豆38 分钟前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部