打印流
字节打印流
特有方法实现:数据原样写出。
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();
}
}
字符打印流
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”
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”
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”压缩包
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()——是将第一个文件夹整体复制到另一个文件夹中。
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:制造假数据
需求:制造假数据也是开发中的一个能力,在各个网上爬取数据,是其中一个方法。
分析:先将各个网址定义出来,再定义一个方法进行网络爬取
只演示一个将姓氏爬取出来:
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)再将修改了的值写入文件中
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;
}
}
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让用户键盘录入用户名和密码
比较用户录入的和正确的用户名密码是否一致
如果一致则打印登陆成功
如果不一致则打印登陆失败,连续输错三次被锁定。
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文件中。