io流
io流的概述
io流的体系
字节输出流基本用法
package mybytestream;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo1 {public static void main(String[] args) throws IOException {/*演示:宁节输出流FileOutputStream实现需求:写出一段文字到本地文件中。(暂时不写中文)实现步骤:创建对象写出数据释放资源*///1.创建对象//1.创建对象//写出 输出流 OutputStream//本地文件FileOutputStream fos=new FileOutputStream("..\\myio\\a.txt");//2.写出数据fos.write(97);//3.释放数据fos.close();}
}
FileOutputStream写数据的3种方式
package mybytestream;import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo2 {public static void main(String[] args) throws IOException {/*void write(int b)一次写一个字节数据void write(byte[] b)一次写一个字节数组数据void write(byte[]b, int off, int len)一次写一个字节数组的部分数据参数一:数组参数二:起始索引参数三:个数*///1.创建对象FileOutputStream fos=new FileOutputStream("..\\myio\\a.txt");//2.写出数据//fos.write(97);//a//fos.write(98);//bbyte[] bytes={97,98,99,100,101};//fos.write(bytes);//abcdefos.write(bytes,1,2);//bc//3.释放资源fos.close();;}
}
换行和续写
package mybytestream;import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDem03 {public static void main(String[] args) throws IOException {/*换行写:再次写出一个换行符就可以了windows:\r\nLinux:\nMac:\r细节:在windows操作系统当中,java对回车换行进行了优化。虽然完整的是\r\n,但是我们写其中一个\r或者\n,java也可以实现换行,因为java在底层会补全。建议:不要省略,还是写全了。续写:如果想要续写,打开续写开关即可开关位置:创建对象的第二个参数默认false:表示关闭续写,此时创建对象会清空文件手动传递true:表示打开续写,此时创建对象不会清空文件*///1.创建对象FileOutputStream fos=new FileOutputStream("..\\myio\\a.txt",true);//2.写出数据String str1="阳雨婵";byte[] bytes1=str1.getBytes();fos.write(bytes1);//再次写出一个换行符就可以了String wrap="\r\n";byte[] bytes2=wrap.getBytes();fos.write(bytes2);String str3="666";byte[] bytes3=str3.getBytes();fos.write(bytes3);//3.释放资源fos.close();}
}
FileInputStream字节输入流的基本用法
package mybytestream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {/*演示:字节输入流FileInputStream实现需求:读取文件中的数据。(暂时不写中文)实现步骤:创建对象读取数据释放资源*///1.创建对象FileInputStream fis=new FileInputStream("..\\myio\\a.txt");//2.读取数据for (int i = 0; i < 5; i++) {int b=fis.read();System.out.println((char)b);}//3.释放资源fis.close();}
}
所需要注意的细节
循环读取
package mybytestream;import java.io.FileInputStream;
import java.io.IOException;public class ByteStreamDemo5 {public static void main(String[] args) throws IOException {/*字节输入流循环读取*///1.创建对象FileInputStream fis=new FileInputStream("..\\myio\\a.txt");//2.循环读取int b;while((b=fis.read())!=-1){System.out.println((char) b);}//3.释放资源fis.close();/*read:表示读取数据,而且是读取一个数据就移动一次指针FileInputStream fis=new FileInputStream("..\\myio\\a.txt");//2.循环读取while((fis.read())!=-1){System.out.println(fis.read());}//3.释放资源fis.close();*/}
}
文件拷贝基本代码
package mybytestream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo6 {public static void main(String[] args) throws IOException {/*练习:文件拷贝注意:选择一个比较小的文件,不要太大*///q.创建对象FileInputStream fis=new FileInputStream("D:\\cd");FileOutputStream fos=new FileOutputStream("..\\myio\\copy");//2.拷贝//核心思想:边读边想int b;while ((b=fis.read())!=-1){fos.write(b);}//释放资源//规则:最先开的最后关闭fos.close();;fis.close();;}
}
字节流一次读取多个字节
package mybytestream;import java.io.FileInputStream;
import java.io.IOException;public class ByteStreamDemo7 {public static void main(String[] args) throws IOException {/*public int read(byte[] buffer) 一次读一个字节数组数据*///1.创建对象FileInputStream fis=new FileInputStream("..\\myio\\a.txt");//2.读取数据byte[] bytes=new byte[2];//一次读取多个字节数据,具体读多少,跟数组的长度有关//返回值:本次读取到了多少个字节数据int len1=fis.read(bytes);System.out.println(len1);//2String str1=new String(bytes,0,len1);System.out.println(str1);//abint len2=fis.read(bytes);System.out.println(len2);//2String str2=new String(bytes,0,len2);System.out.println(str2);//cdint len3=fis.read(bytes);System.out.println(len3);//1String str3=new String(bytes,0,len3);System.out.println(str3);//e//3.释放数据fis.close();}
}
用此方法进行文件拷贝
package mybytestream;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo8 {public static void main(String[] args) throws IOException {/*练习:文件拷贝(27.0MB)*/long start=System.currentTimeMillis();//1.创建对象FileInputStream fis=new FileInputStream("D:\\腾讯会议\\WeMeet\\3.31.2.441\\wemeet_app_components.dll");FileOutputStream fos=new FileOutputStream("..\\myio\\copy.dll");//2.拷贝int len;byte[] bytes=new byte[1024*1024*5];while((len=fis.read(bytes))!=-1){fos.write(bytes,0,len);}//3.释放资源fos.close();fis.close();long end=System.currentTimeMillis();System.out.println(end-start);//40ms}
}
io流中的异常处理
finally中的语句一定会执行,所有可以将释放资源的代码用finally控制,确保资源能正常释放。
字符集详解
(GBK)
在计算机中,任意数据都是以二进制的形式来存储的
存储英文,一个字节足以
核心1:GBK中,一个英文字母一个字节,二进制第一位是0
核心2:GBK中,一个中文汉字两个字节,二进制第一位是1
(Unicode)
UTF-8不是字符集,是Unicode字符集的一种编码方式。
为什么会有乱码
原因1:读取数据时未读完整个汉字
原因2:编码和解码的方式不统一
拷贝时是一个字节一个字节进行拷贝的,所有使用字节流拷贝也不会出现乱码
java中的编码和解码
package mycharset;import java.io.UnsupportedEncodingException;
import java.sql.SQLOutput;
import java.util.Arrays;public class CharSetDemo1 {public static void main(String[] args) throws UnsupportedEncodingException {/*Java中编码的方法public byte[] getBytes()使用默认方式进行编码public byte[] getBytes(string charsetName) 使用指定方式进行编码Java中解码的方法String(byte[] bytes)使用默认方式进行解码String(byte[l bytes, string charsetName)使用指定方式进行解码*///1.编码String str="ai你哟";byte[] bytes1=str.getBytes();System.out.println(Arrays.toString(bytes1));byte[] bytes2=str.getBytes("GBK");System.out.println(Arrays.toString(bytes2));//2.解码String str2=new String(bytes1);System.out.println(str2);String str3=new String(bytes1,"GBK");System.out.println(str3);}
}
字符流
FIleReader字符输入流
空参read方法详解
package mycharstream1;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class CharStreamDemo1 {public static void main(String[] args) throws IOException {/*第一步:创建对象public FileReader(File file)创建字符输入流关联本地文件public FileReader(string pathname)创建字符输入流关联本地文件第二步:读取数据public int read()读取数据,读到末尾返回-1public int read(char[] buffer)读取多个数据,读到末尾返回-1第三步:释放资源public void close()释放资源/关流*///1创建对象并关联本地文件FileReader fr=new FileReader(("..\\myio\\a.txt"));//2.读取数据 read()//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节//read()细节://1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个//2.在读取之后,方法的底层还会进行解码并转成十进制。//最终把这个十进制作为返回值//这个十进制的数据也表示在字符集上的数字//英文:文件里面二进制数据 0118 0001//read方法进行读取,解码并转成十进制97//中义:文件里面的二进制数据 11100110 10110801 10001001//read方法进行读取,解码并转成十进制27721//我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了int ch;while((ch=fr.read())!=-1){System.out.print((char) ch);}}
}
有参read方法详解
package mycharstream1;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class CharStreamDemo2 {public static void main(String[] args) throws IOException {/*第一步:创建对象public FileReader(File file)创建字符输入流关联本地文件public FileReader(string pathname)创建字符输入流关联本地文件第二步:读取数据public int read()读取数据,读到末尾返回-1public int read(char[] buffer)读取多个数据,读到末尾返回-1第三步:释放资源public void close()释放资源/关流*///1.创建对象FileReader fr = new FileReader("..\\myio\\a.txt");//2.读取数据char[] chars = new char[2];int len;//read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中//空参的read + 强转类型转换while ((len = fr.read(chars)) != -1) {//把数组中的数据变成字符串再进行打印System.out.print(new String(chars, 0, len));}//3.释放资源fr.close();}
}
FileWriter字符输出流
package mycharstream1;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class CharStreamDemo3 {public static void main(String[] args) throws IOException {/*第一步:创建对象public FileWriter(File file)创建字符输出流关联本地文件public FileWriter(string pathname)创建字符输出流关联本地文件public FileWriter(File file, boolean append)创建字符输出流关联本地文件,续写public FileWriter(string pathname, boolean append)创建字符输出流关联本地文件,续写第二步:读取数据void write(int c)写出一个字符void write(string str)写出一个字符串void write(string str, int off, int len)写出一个字符串的一部分void write(char[] cbuf)写出一个字符数组void write(char[] cbuf, int off, int len)写出字符数组的一部分第三步:释放资源public void close()释放资源/关流'我' 25105*/FileWriter fw=new FileWriter("..\\myio\\a.txt",true);//fw.write(25105);//fw.write("你好威啊???");char[] chars={'a','b','c','我'};fw.write(chars);fw.close();}
}
字符流原理解析
练习
1.拷贝
package Test;import java.io.*;
import java.lang.reflect.Field;public class Test1 {public static void main(String[] args) throws IOException {File src=new File("D:\\应用\\Inno Setup 5\\Languages");File dest=new File("D:\\aaa\\dest");copydir(src,dest);}public static void copydir(File src,File dest) throws IOException {dest.mkdirs();File[] files=src.listFiles();for(File file:files){if(file.isFile()){FileInputStream fis=new FileInputStream(file);FileOutputStream fos=new FileOutputStream(new File(dest,file.getName()));byte[] bytes=new byte[1024];int len;while((len=fis.read(bytes))!=-1){fos.write(bytes,0,len);}fos.close();fis.close();}else{copydir(file,new File(dest,file.getName()));}}}
}
2.文件加密
package Test;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Test2 {public static void main(String[] args) throws IOException {/*异或两边相同:false两边不同:true一个数异或两次同一个数会得到他本身*///创建对象关联原始文件FileInputStream fis=new FileInputStream("..\\myio\\ency.jpg");//创建对象管理加密文件FileOutputStream fos=new FileOutputStream("..\\myio\\redu.jpg");//3。加密处理int b;while((b=fis.read())!=-1){fos.write(b^2);}//4.释放资源fos.close();fis.close();}
}
3.修改文件中的数据
package Test;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;public class Test3 {public static void main(String[] args) throws IOException {/*文本文件中有以下的数据:2-1-9-4-7-8将文件中的数据进行排序,变成以下的数据:1-2-4-7-8-9*///1.读取数据FileReader fr=new FileReader("..\\myio\\a.txt");StringBuilder sb=new StringBuilder();int ch;while((ch=fr.read())!=-1){sb.append((char)ch);}fr.close();//2.排序Integer[] arr = Arrays.stream(sb.toString().split("-")).map(Integer::parseInt).sorted().toArray(Integer[]::new);//3.写出FileWriter fw=new FileWriter("..\\myio\\a.txt");String s=Arrays.toString(arr).replace(", ","-");String result=s.substring(1,s.length()-1);fw.write(result);fw.close();}
}
缓冲流
BUfferedInputStream字节缓冲流
一次读取一个字节
package mybufferedstream1;import java.io.*;public class BufferedStreamDemo1 {public static void main(String[] args) throws IOException {/*需求:利用字节缓冲流拷贝文件字节缓冲输入流的构造方法:public BufferedInputStream(Inputstream is)字节缓冲输出流的构造方法:public Bufferedoutputstream(outputstream os)*///1.创建缓冲流的对象BufferedInputStream bis=new BufferedInputStream(new FileInputStream("..\\myio\\a.txt"));BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("..\\myio\\copy.txt"));//2.循环读取并写到目的地int b;while((b=bis.read())!=-1){bos.write(b);}//3.释放资源bos.close();bis.close();}
}
一次读取多个字节
package mybufferedstream1;import java.io.*;public class BufferedStreamDemo2 {public static void main(String[] args) throws IOException {/*需求:利用字节缓冲流拷贝文件字节缓冲输入流的构造方法:public BufferedInputStream(Inputstream is)字节缓冲输出流的构造方法:public Bufferedoutputstream(outputstream os)*///1.创建缓冲流的对象BufferedInputStream bis=new BufferedInputStream(new FileInputStream("..\\myio\\a.txt"));BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("..\\myio\\copy2.txt"));//2.循环读取并写到目的地byte[] bytes=new byte[1024];int len;while((len=bis.read(bytes))!=-1){bos.write(bytes,0,len);//3.释放资源bos.close();bis.close();}
}
BufferedReader字符缓冲流
输入
package mybufferedstream1;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class BufferedStreamDemo3 {public static void main(String[] args) throws IOException {/*字符缓冲输入流:构造方法:public BufferedReader(Reader r)特有方法:public string readLine()谈一整行*///1.创建字符缓冲输入流的对象BufferedReader br=new BufferedReader(new FileReader("..\\myio\\a.txt"));//细节://readLine方法在读取的时候,一次读一整行,遇到回车换行结束//但是他不会把回车换行读到内存当中//2.读取数据String line1=br.readLine();System.out.println(line1);String line2=br.readLine();System.out.println(line2);//3.释放资源br.close();}
}
输出
package mybufferedstream1;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;public class BufferedStreamDemo4 {public static void main(String[] args) throws IOException {/*字符缓冲输出流构造方法:public BufferedWriter(Writer r)特有方法:public void newLine()跨平台的换行*///1.创建字符缓冲输出流的对象BufferedWriter bw=new BufferedWriter(new FileWriter("b.txt",true));//2.写出数据bw.write("123");bw.newLine();bw.write("456");bw.newLine();//3.释放资源bw.close();}
}
练习
1.修改文本顺序
package Test;import java.io.*;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;public class Test4 {public static void main(String[] args) throws IOException {//1.读取数据BufferedReader br=new BufferedReader(new FileReader("..\\myio\\a.txt"));String line;TreeMap<Integer,String> tm=new TreeMap<>();while((line=br.readLine())!=null){String[] arr=line.split("\\.");tm.put(Integer.parseInt(arr[0]),arr[1]);}br.close();//2.写出数据BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myio\\result.txt"));Set<Map.Entry<Integer,String>> entries=tm.entrySet();for (Map.Entry<Integer, String> entry : entries) {String value=entry.getValue();bw.write(value);bw.newLine();}bw.close();}
}
2.软件运行次数
package Test;import java.io.*;public class Test5 {public static void main(String[] args) throws IOException {/*实现验证在序运行实数的小程序,要求如下1.当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用~2.程序运行演示如下:第一次运行控制台输出:欢迎使用本软件,第1次使用免费~第二次运行控制台输出:欢迎使用本软件,第2次使用免费~第三次运行控制台输出:欢迎使用本软件,第3次使用免费~第四次及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~次数 计数器int count =0;*///1.把文件中的数字读取到内存中//原则://IO://随用随创建//什么时候不用什么时候关闭BufferedReader br=new BufferedReader(new FileReader("..\\myio\\count.txt"));String line=br.readLine();br.close();int count=Integer.parseInt(line);count++;//2.判断if(count<=3){System.out.println("欢迎使用本软件,第"+count+"次使用免费~");}else{System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用~");}BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myio\\count.txt"));bw.write(count+"");bw.close();}
}
InputStreamReader/OutputStreamWriter转换流
1.转换流的基本用法
JDK11以前可以使用转换流按照指定字符编码读取和写入
JDK11以后字符流中添加了一个新歌构造指定字符编码
练习:读取文件中的数据
package myconvertstream;import java.io.*;public class ConvertStreamDemo1 {public static void main(String[] args) throws IOException {/*利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码//1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定//2.字节流里面是没有读一整行的方法的,只有字符缓冲流才能搞定*/BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("..\\myio\\a.txt")));String line;while((line=br.readLine())!=null){System.out.println(line);}br.close();}
}
总结
序列化流和反序列化流
ObjectOutputStream序列化流
package myobjectstream;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class ObjectStreamDemo1 {public static void main(String[] args) throws IOException {/*需求:利用序列化流/对象操作输出流,把一个对象写到本地文件中构造方法:public objectoutputstream(outputstream out)成员方法:public final void writeobject(object obj)把基本流变成高级流把对象序列化(写出)到文件中去*///1.创建对象Student stu=new Student("zhangsan",23);//2.创建序列化流的对象/对线操作输出流ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\myio\\b.txt"));//3.写出数据oos.writeObject(stu);//4.释放数据oos.close();}
}
package myobjectstream;import java.io.Serializable;/*
Serializable接口里面是没有抽象方法,标记型接口
一旦实现了这个接口,那么就表示当前的student类可以被序列化
理解:
-个物品的合格证*/
public class Student implements Serializable {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
ObjectInputStream反序列化流
package myobjectstream;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class ObjectStreamDemo2 {public static void main(String[] args) throws IOException, ClassNotFoundException {/*求:利用反序列化流/对象操作输入流,把文件中中的对象读到程序当中构造方法:public objectInputstream(Inputstream out)成员方法:把基本流变成高级流public obiect readobiect()把序列化到本地文件中的对象,读取到程序中来*///1.创建反序列化流的对象ObjectInputStream ois=new ObjectInputStream(new FileInputStream("..\\myio\\b.txt"));//2.读取数据Student stu=(Student) ois.readObject();//3.打印对象System.out.println(stu);//4.释放资源ois.close();}
}
细节
package myobjectstream;import java.io.Serial;
import java.io.Serializable;/*
Serializable接口里面是没有抽象方法,标记型接口
一旦实现了这个接口,那么就表示当前的student类可以被序列化
理解:
-个物品的合格证*/
public class Student implements Serializable {@Serialprivate static final long serialVersionUID = 3340324615881368858L;private String name;private int age;//transient:瞬态关键字//作用:不会把当前属性序列化到本地文件当中private transient String address;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
练习
package Test;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;public class Test6 {public static void main(String[] args) throws IOException {/*需求:将多个自定义对象序列化到文件中,但是对象的个数不确定,该如何操作呢*///1.序列化多个对象Student s1=new Student("zhangsan",25,"邵阳");Student s2=new Student("lisi",26,"衡阳");Student s3=new Student("wangwu",27,"隆回");ArrayList<Student> list=new ArrayList<>();Collections.addAll(list,s1,s2,s3);ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\myio\\b.txt"));oos.writeObject(list);oos.close();}
}
打印流
打印流不能读只能写
PrintStream字节打印流
构造方法
成员方法
练习
package myprintstream;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;public class PrintStreamDemo1 {public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {/*字节打印流:构造方法public Printstream(outputstream/File/string)关联字节输出流/文件/文件路径public Printstream(string fileName,Charset charset)指定字符编码public Printstream(outputstreamout,boolean autoFlush)自动刷新public Printstream(outputstream out, boolean autoFlush, string encoding)指定字符编码且自动刷新成员方法:public void write(int b)常规方法:规则跟之前一样,将指定的字节写出public void println(Xxx xx)特有方法:打印任意数据,自动刷新,自动换行public void print(Xxx xx)特有方法:打印任意数据,不换行public void printf(string format,object... args) 特有方法:带有占位符的打印语句,不换行*///1.创建字节打印流的对象PrintStream ps=new PrintStream(new FileOutputStream("..\\myio\\a.txt"),true,"UTF-8");//2.写出数据ps.println(97);ps.print(true);ps.println();ps.printf("%s爱上了%s","阿珍","阿强");//3.释放资源ps.close();}
}
PrintWriter字符打印流
构造方法
成员方法
打印流的应用场景
package myprintstream;import java.io.PrintStream;public class PrintStreamDemo3 {public static void main(String[] args) {/*打印流的应用场景*///获取打印流的对象,此打印流在虚拟机启动的时候,由虚拟机创建,默认指向控制台//特殊的打印流,系统中的标准输出流,是不能关闭,在系统中是唯一的。PrintStream ps=System.out;//调用打印流中的方法println//写出数据,自动换行,自动刷新ps.println("123");//ps.close();;ps.println("你好你好");System.out.println("456");}
}
总结
解压缩流/压缩流
解压缩流
压缩包中的每一个文件或者文件夹都是一个ZipEntry对象。
package myzipstream;import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;public class ZipStreamDemo1 {public static void main(String[] args) throws IOException {//1.创建一个File表示要解压的压缩包File src=new File("D:\\aaa.zip");//2.创建一个File表示解压的目的地File dest=new File("D:\\");//调用方法unzip(src,dest);}//定义一个方法来解压public static void unzip(File src,File dest) throws IOException {//解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中//创建一个解压缩流用来读取压缩包中的数据ZipInputStream zip=new ZipInputStream(new FileInputStream(src));//要先获取到压缩包里面的每一个zipentry对象//表示当前在压缩包中获取到的文件或者文件夹ZipEntry entry;while((entry=zip.getNextEntry())!=null){System.out.println(entry);if(entry.isDirectory()){//文件夹:需要在目的地dest处创建一个同样的文件夹File file=new File(dest,entry.toString());file.mkdirs();}else{//文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)FileOutputStream fos=new FileOutputStream(new File(dest,entry.toString()));int b;while((b=zip.read())!=-1){//写到目的地fos.write(b);}fos.close();//表示在压缩包中的一个文件处理完毕了zip.closeEntry();}}zip.close();}
}
压缩流
package myzipstream;import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;public class ZipStreamDemo2 {public static void main(String[] args) throws IOException {/*压缩流需求:把D:\a.txt打包成一个压缩包*///1.创建File对象表示要压缩的文件File src=new File("D:\\a.txt");//2.创建File对象表示压缩包的位置File dest=new File("D:\\");//3.调用方法用来压缩toZip(src,dest);}/*作用:压缩参数一:表示要压缩的文件参数二:表示压缩包的位置*/public static void toZip(File src,File dest) throws IOException {//1.创建压缩流关联压缩包ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));//2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹ZipEntry entry=new ZipEntry("a.txt");//3.把ZipEntry对象放到压缩包当中zos.putNextEntry(entry);//4.把src文件中的数据写到压缩包当中FileInputStream fis=new FileInputStream(src);int b;while((b=fis.read())!=-1){zos.write(b);}zos.closeEntry();zos.close();}
}
常用工具包
Commons-io
经典白雪,那我之前敲的代码算什么,算孩子有劲吗
Hutool工具包
练习
1.爬虫获取姓名
package myiotest1;import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test1 {public static void main(String[] args) throws IOException {/*制造假数据:获取男生名字:http://www.haoming8.cn/baobao/10881.htm1获取姓氏:https://hanyu.baidu.com/shici/detail?pid=0b2f26d4ceddb3ee693fdb1137ee1bed&from=kg0获取女生名字:http://www.haoming8.cn/baobao/7641.html*///1.定义变量记录网址String familyNameNet="https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";String boyNameNet="http://www.haoming8.cn/baobao/10881.htm1";String girlNameNet="http://www.haoming8.cn/baobao/7641.html";//2.爬取数据,把网址上所有数据拼接成一个字符串String familyNameStr= webCrawler(familyNameNet);String boyNameStr= webCrawler(familyNameNet);String girlNameStr= webCrawler(familyNameNet);//3.通过正则表达式,把其中符合要求的数据获取出来ArrayList<String> familyNameTempList=getData(familyNameStr,"(\\W{4})(。|,)",1);ArrayList<String> boyNameTempList=getData(boyNameStr,"([\\u4E00-\\u9FA5]{2})(。|、)",1);ArrayList<String> girlNameTempList=getData(girlNameStr,"(.. ){4}..",0);//4.处理数据//familyNameTempList(姓氏)//处理方案:把每一个姓氏拆开并添加到一个新的集合当中ArrayList<String> familyNameList=new ArrayList<>();for(String str:familyNameTempList){//str 赵钱孙李 周吴郑王 冯陈褚卫 蒋沈韩杨for (int i = 0; i < str.length(); i++) {char c=str.charAt(i);familyNameList.add(c+"");}}//boyNameTempList(男生的名字)//处理方案:去除其中的重复元素ArrayList<String> boyNameList=new ArrayList<>();for (String str : boyNameList) {if(!boyNameList.contains(str)){boyNameList.add(str);}}//girlNameTempList(女生的名字)//处理方案:把里面的每一个元素用空格进行切割,得到每一个女生的名字ArrayList<String> girlNameList=new ArrayList<>();for (String str : girlNameList) {String[] arr=str.split(" ");for (int i = 0; i < arr.length; i++) {girlNameList.add(arr[i]);}}//5.生成数据//姓名(唯一)-性別-年龄ArrayList<String> list=getInfos(familyNameList,boyNameList,girlNameList,70,80);System.out.println(list);//写出数据BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myio\\names.txt"));for (String str : list) {bw.write(str);bw.newLine();}bw.close();}/*作用:获取男生和女生的信息:张三-男-23涨形参:参数一:装着姓氏的集合参数二:装着男生名字的集合参数三:装着女生名字的集合参数四:男生的个数参数五:女生的个数*/public static ArrayList<String> getInfos(ArrayList<String> familyNameList,ArrayList<String> boyNameList,ArrayList<String> girlNameList,int boyCount,int girlCount){//1.生成不重复的名字HashSet<String> boyhs=new HashSet<>();while(true){if(boyhs.size()==boyCount){break;}//随机Collections.shuffle(familyNameList);Collections.shuffle(boyNameList);boyhs.add(familyNameList.get(0)+boyNameList.get(0));}//2.生成女生不重复的名字HashSet<String> girlhs=new HashSet<>();while(true){if(girlhs.size()==girlCount){break;}//随机Collections.shuffle(familyNameList);Collections.shuffle(girlNameList);boyhs.add(familyNameList.get(0)+girlNameList.get(0));}//3.生成男生的信息并添加到集合当中ArrayList<String> list=new ArrayList<>();Random r=new Random();//[18~27]for (String boyName : boyhs) {int age=r.nextInt(10)+18;list.add(boyName+"男"+age);}//3.生成女生的信息并添加到集合当中//[18~25]for (String girlName : girlhs) {int age=r.nextInt(8)+18;list.add(girlName+"女"+age);}return list;}/*作用:根据正则表达式获取字符串中的数据参数一:完整的字符串参数二:正则表达式参数三:???返回值:真正想要的数据*/private static ArrayList<String> getData(String str,String regex,int index){//1.创建集合存放数据ArrayList<String> list=new ArrayList<>();//2.按照正则表达式的规则,去获取数据Pattern pattern=Pattern.compile(regex);//按照Pattern的规则,到str中去获取数据Matcher matcher=pattern.matcher(str);while(matcher.find()){list.add(matcher.group(index));}return list;}/*作用:从网络中爬取数据,把数据拼接成字符串返回形参:网址返回值:爬取到的所冇数据*/public static String webCrawler(String net) throws IOException {//1.定义StringBuilder拼接爬取到的数据StringBuilder sb=new StringBuilder();//2.创建一个URL对象URL url=new URL(net);//3.链接上这个网址//细节:保证网络是畅通的,而且这个网址是可以链接上的。URLConnection conn=url.openConnection();//4.读取数据InputStreamReader isr=new InputStreamReader(conn.getInputStream());int ch;while((ch= isr.read())!=-1){sb.append((char)ch);}//5.释放资源isr.close();;return sb.toString();}
}
2.随机点名器
1.
package myiotest2;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;public class Test1 {public static void main(String[] args) throws IOException {/*需求:需求:有一个文件里面存储了班级同学的信息,每一个信息占一行。格式为:张三-男-23要求通过程序实现随机点名器。运行效果:第一次运行程序:随机同学姓名1(只显示名字)第二次运行程序:随机同学姓名2(只显示名字)第三次运行程序:随机同学姓名3(只显示名字)…*///1.读取文件中学生的姓名ArrayList<String> list=new ArrayList<>();BufferedReader br=new BufferedReader(new FileReader("..\\myiotest\\allnames.txt"));String line;while((line=br.readLine())!=null){list.add(line);}br.close();//2.随机抽取Collections.shuffle(list);String randomName=list.get(0);String[] arr2=randomName.split("-");System.out.println(arr2[0]);}
}
2.
package myiotest2;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;public class Test2 {public static void main(String[] args) throws IOException {/*需求:一个文件里面存储了班级同学的信息,每一个学生信息占一行。格式为:张三-男-23。要求通过程序实现随机点名器运行效果:70%的概率随机到男生30%的概率随机到女生总共随机100万次,统计结果。注意观察:看生成男生和女生的比例是不是接近于7:3*///1.读取文件中的姓名,按性别存放到数组中ArrayList<String> boylist=new ArrayList<>();ArrayList<String> girllist=new ArrayList<>();BufferedReader br=new BufferedReader(new FileReader("..\\myiotest\\allnames.txt"));String line;while((line=br.readLine())!=null){if(line.split("-")[1].equals("男")){boylist.add(line);}else{girllist.add(line);}}br.close();//按概率抽取Random r=new Random();int a=0,b=0;for(int i=1;i<=100000;i++){int x= r.nextInt(10)+1;Collections.shuffle(boylist);Collections.shuffle(girllist);if(x<=7){a++;}else{b++;}}System.out.println(a);System.out.println(b);}
}
3.
package myiotest2;import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;public class Test3 {public static void main(String[] args) throws IOException {/*需求:一个文件里面存储了班级同学的姓名,每一个姓名占一行。要求通过程序实现随机点名器,第三次必定是张三同学运行效果:第一次运行程序随机同学姓名1第二次运行程序:随机同学姓名2第三次运行程序:张三*///读取文件中学生的姓名ArrayList<String> list=new ArrayList<>();BufferedReader br1=new BufferedReader(new FileReader("..\\myiotest\\allnames.txt"));String line;while((line=br1.readLine())!=null){list.add(line);}br1.close();//读取程序运行的次数BufferedReader br2=new BufferedReader(new FileReader("..\\myiotest\\count.txt"));String strcount=br2.readLine();int count=Integer.parseInt(strcount);br2.close();count++;if(count!=3){Collections.shuffle(list);Arrays.stream(list.get(0).split("-")).limit(1).forEach(System.out::println);}else{System.out.println("张三");}//将程序运行次数存入文件BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myiotest\\count.txt"));bw.write(count+"");bw.close();}
}
4.
package myiotest2;import java.io.*;
import java.util.ArrayList;
import java.util.Collections;public class Test5{public static void main(String[] args) throws IOException {/*需求:一个文件里面存储了班级同学的姓名,每一个姓名占一行。要求通过程序实现随机点名器。运行结果要求:被点到的学生不会再被点到。但是如果班级中所有的学生都点完了, 需要重新开启第二轮点名。核心思想:点一个删一个,把删除的备份,全部点完时还原数据。*///1.定义变量,表示初始文件路径,文件中存储所有的学生信息String src = "..\\myiotest\\names.txt";//2.定义变量,表示备份文件,一开始文件为空String backups = "..\\myiotest\\backups.txt";//3.读取初始文件中的数据,并把学生信息添加到集合当中ArrayList<String> list = readFile(src);//4.判断集合中是否有数据if (list.size() == 0) {//5.如果没有数据,表示所有学生已经点完,从backups.txt中还原数据即可//还原数据需要以下步骤://5.1 读取备份文件中所有的数据list = readFile(backups);//5.2 把所有的数据写到初始文件中writeFile(src, list, false);//5.3 删除备份文件new File(backups).delete();}//5.集合中有数据,表示还没有点完,点一个删一个,把删除的备份到backups.txt当中//打乱集合Collections.shuffle(list);//获取0索引的学生信息并删除String stuInfo = list.remove(0);//打印随机到的学生信息System.out.println("当前被点到的学生为:" + stuInfo);//把删除之后的所有学生信息,写到初始文件中writeFile(src, list, false);//把删除的学生信息备份(追加写入)writeFile(backups, stuInfo, true);}private static void writeFile(String pathFile, ArrayList<String> list, boolean isAppend) throws IOException {BufferedWriter bw = new BufferedWriter(new FileWriter(pathFile, isAppend));for (String str : list) {bw.write(str);bw.newLine();}bw.close();}private static void writeFile(String pathFile, String str, boolean isAppend) throws IOException {BufferedWriter bw = new BufferedWriter(new FileWriter(pathFile, isAppend));bw.write(str);bw.newLine();bw.close();}private static ArrayList<String> readFile(String pathFile) throws IOException {ArrayList<String> list = new ArrayList<>();BufferedReader br = new BufferedReader(new FileReader(pathFile));String line;while ((line = br.readLine()) != null) {list.add(line);}br.close();return list;}
}
5.
package myiotest3;import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;public class Test1 {public static void main(String[] args) throws IOException {//1.把文件中的所以学生信息读取到内存中ArrayList<Student> list=new ArrayList<>();BufferedReader br=new BufferedReader(new FileReader("..\\myiotest\\names.txt"));String line;while((line=br.readLine())!=null){String[] arr=line.split("-");list.add(new Student(arr[0],arr[1],Integer.parseInt(arr[2]),Double.parseDouble(arr[3])));}br.close();//2.计算权重的总和double weight=0;for (Student stu : list) {weight+= stu.getWeight();}//3.计算每一个人的实际占比double[] arr=new double[list.size()];int index=0;for (Student stu : list) {arr[index++]= stu.getWeight()/weight;}//4.计算每一个人的权重占比范围for (int i = 1; i < arr.length; i++) {arr[i]+=arr[i-1];}//5.随机抽取//获取一个0.0~1.0之间的随机数double number=Math.random();//判断number在arr中的位置//二分查找法//方法回返回:-插入点 -1int result=-Arrays.binarySearch(arr,number)-1;Student stu=list.get(result);System.out.println(stu);//6.修改当前学生的权重double w= stu.getWeight()/2;stu.setWeight(w);//7.把集合中的数据再次写到文件中BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myiotest\\names.txt"));for (Student s : list) {bw.write(s.toString());bw.newLine();}bw.close();}
}
登录注册
package myiotesy4;import java.io.*;
import java.util.Scanner;public class Test1 {public static void main(String[] args) throws IOException {/*需求:写一个登陆小案例添加锁定账号功能)步骤:将正确的用户名和密码手动保存在本地的自userinfo.txt文件中保存格式为:username=zhangsan&password=123&count=0让用户键盘录入用户名和密码比较用户录入的和正确的用户名密码是否一致如果一致则打印登陆成功如果不一致则打印登陆失败输错三次被锁定*///1.读取正确用户名密码和登陆失败次数BufferedReader br=new BufferedReader(new FileReader("..\\myiotest\\src\\myiotesy4\\userinfo.txt"));String line=br.readLine();br.close();String[] useInfo=line.split("&");String[] arr1=useInfo[0].split("=");String[] arr2=useInfo[1].split("=");String[] arr3=useInfo[2].split("=");String rightUsername=arr1[1];String rightPassword=arr2[1];//count:表示用户连续输错的次数int count=Integer.parseInt(arr3[1]);//2.用户键盘录入用户名和密码if(count==3){System.out.println("用户账户锁定");}else {Scanner sc=new Scanner(System.in);System.out.println("请输入用户名");String username=sc.nextLine();System.out.println("请输入密码");String password=sc.nextLine();//3.比较if(rightUsername.equals(username)&&rightPassword.equals(password)){System.out.println("登录成功");count=0;}else {count++;System.out.println("登录失败,还剩下"+(3-count)+"次机会");}//4.把登录失败次数打印到文件当中BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myiotest\\src\\myiotesy4\\userinfo.txt"));bw.write("username=" + rightUsername + "&password=" + rightPassword + "&count="+String.valueOf(count));bw.close();}}
}
properties
properties是配置文件的一种
Properties作为双列集合的方法
package myiotest5;import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;public class Test1 {public static void main(String[] args) {/*Properties作为Map集合的操作*///1.添加集合的对象Properties prop=new Properties();//2.添加数据//细节:虽然我们可以往Properties当中添加任意的数据类型,但是一般只会往里面添加字符串类型的数据prop.put("aaa","111");prop.put("bbb","222");prop.put("ccc","333");prop.put("ddd","444");//3.遍历集合/*Set<Object> keys=prop.keySet();for (Object key : keys) {Object value=prop.get(key);System.out.println(key+"="+value);}*/Set<Map.Entry<Object,Object>> entries=prop.entrySet();for (Map.Entry<Object, Object> entry : entries) {Object key=entry.getKey();Object value=entry.getValue();System.out.println(key+"="+value);}}
}
Properties中特有的读写方法
写
package myiotest5;import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class Test2 {public static void main(String[] args) throws IOException {/*Properties跟IO流结合的操作*///1.创建集合Properties prop=new Properties();//2.添加数据prop.put("aaa","111");prop.put("bbb","222");prop.put("ccc","333");prop.put("ddd","444");//3.把集合中的数据以键值对的形式写到本地文件当中FileOutputStream fos=new FileOutputStream("..\\myiotest\\a.properties");prop.store(fos,"test");fos.close();/*BufferedWriter bw=new BufferedWriter(new FileWriter("..\\myiotest\\a.properties"));Set<Map.Entry<Object,Object>> entries=prop.entrySet();for (Map.Entry<Object, Object> entry : entries) {Object key=entry.getKey();Object value=entry.getValue();bw.write(key+"="+value);bw.newLine();}bw.close();*/}
}
读
package myiotest5;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;public class Test3 {public static void main(String[] args) throws IOException {//1.创建集合Properties prop=new Properties();//2.读取本地Properties文件里面的数据FileInputStream fis=new FileInputStream("..\\myiotest\\a.properties");prop.load(fis);fis.close();//3.打印集合System.out.println(prop);}
}
拼图游戏
游戏界面
package ui;import domain.GameInfo;import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.util.Properties;
import java.util.Random;public class GameJFrame extends JFrame implements KeyListener, ActionListener {//表示游戏的主界面//彩蛋int flag;//创建一个二维数组//目的:用来管理数据//加载图片的时候,根据二维数组中的数据,加载对应的图片int[][] data = new int[4][4];//记录空白方块在二维数组中的索引int x = 0;int y = 0;//定义一个变量,记录当前展示图片的路径String path = "..\\puzzlegame\\image\\animal\\animal3\\";//定义一个二维数组,用来判断胜利int[][] win = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};//定义一个变量,用来统计步数int step = 0;//创建选项下面的条目对象JMenuItem girlJMenuItem = new JMenuItem("美女");JMenuItem animalJMenuItem = new JMenuItem("动物");JMenuItem sportJMenuItem = new JMenuItem("运动");JMenuItem replayJMenuItem = new JMenuItem("重新游戏");JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");JMenu saveJMenu = new JMenu("存档");JMenu loadJMenu = new JMenu("读档");JMenuItem saveItem0 = new JMenuItem("存档0(空)");JMenuItem saveItem1 = new JMenuItem("存档1(空)");JMenuItem saveItem2 = new JMenuItem("存档2(空)");JMenuItem saveItem3 = new JMenuItem("存档3(空)");JMenuItem saveItem4 = new JMenuItem("存档4(空)");JMenuItem loadItem0 = new JMenuItem("读档0(空)");JMenuItem loadItem1 = new JMenuItem("读档1(空)");JMenuItem loadItem2 = new JMenuItem("读档2(空)");JMenuItem loadItem3 = new JMenuItem("读档3(空)");JMenuItem loadItem4 = new JMenuItem("读档4(空)");JMenuItem accountJMenuItem = new JMenuItem("公众号");public GameJFrame(int flag){//彩蛋this.flag=flag;System.out.println(this.flag);//初始化界面initJFrame();//初始化菜单initJMenuBar();//初始化数据(打乱图片的顺序)initData();//初始化图片(根据打乱后的顺序加载图片)initImage();//让界面显示出来this.setVisible(true);}//初始化数据(打乱图片的顺序)private void initData() {//1.定义一个一维数组int[] tempArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//2.打乱数组中数据的顺序//遍历数组,得到数组中的每一个元素,拿着每一个元素跟随机索引上的元素进行交换Random r = new Random();for (int i = 0; i < tempArr.length; i++) {//获取到随机索引int index = r.nextInt(tempArr.length);//拿着当前索引上的元素跟随机索引上的元素进行交换int temp = tempArr[i];tempArr[i] = tempArr[index];tempArr[index] = temp;}//3.遍历一维数组,把一维数组中的元素放到二维数组中for (int i = 0; i < tempArr.length; i++) {if(tempArr[i] == 0){//记录0的索引x = i/4;y = i%4;}//i/4 表示二维数组的行索引//i%4 表示二维数组的列索引data[i/4][i%4] = tempArr[i];}}//初始化图片//添加图片的时候,按照二维数组中的数据,来添加图片private void initImage() {//清空原本已经出现的所有图片this.getContentPane().removeAll();if(victory()){//添加胜利的图片JLabel winJLabel = new JLabel(new ImageIcon("..\\puzzlegame\\image\\win.png"));winJLabel.setBounds(203,283,197,73);//把图片添加到界面中this.getContentPane().add(winJLabel);}//添加步数JLabel stepJLabel = new JLabel("步数:"+step);stepJLabel.setBounds(50,30,100,20);//把步数添加到界面中this.getContentPane().add(stepJLabel);//先添加的图片在上方,后添加的图片在下方//外循环---把内循环的代码重复执行4次for (int i = 0; i < 4; i++) {//内循环---表示在一行添加四张图片for (int j = 0; j < 4; j++) {//获取当前要加载图片的序号int num = data[i][j];//创建一个JLabel的对象(管理容器)JLabel jLabel = new JLabel(new ImageIcon(path + num+ ".jpg"));//指定图片的位置jLabel.setBounds(105*j+83,105*i+134,105,105);//给图片添加边框jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));//把管理容器添加到界面中this.getContentPane().add(jLabel);//添加一次之和number需要自增,表示下一次加载后面一张图片}}//添加背景图片JLabel background = new JLabel(new ImageIcon("..\\puzzlegame\\image\\background.png"));background.setBounds(40,40,520,600);//把背景图片添加到界面中this.getContentPane().add(background);//刷新界面this.getContentPane().repaint();}//创建菜单private void initJMenuBar() {//创建整个的菜单对象JMenuBar jMenuBar = new JMenuBar();//创建菜单上面的两个选项的对象(功能 关于我们)JMenu functionJMenu = new JMenu("功能");JMenu aboutJMenu = new JMenu("关于我们");JMenu changeJMenu = new JMenu("更换图片");//将每一个选项下面的条目添加到选项当中//把5个存档,添加到saveJMenu中saveJMenu.add(saveItem0);saveJMenu.add(saveItem1);saveJMenu.add(saveItem2);saveJMenu.add(saveItem3);saveJMenu.add(saveItem4);//把5个读档,添加到loadJMenu中loadJMenu.add(loadItem0);loadJMenu.add(loadItem1);loadJMenu.add(loadItem2);loadJMenu.add(loadItem3);loadJMenu.add(loadItem4);//把美女,动物,运动添加到更换图片当中changeJMenu.add(girlJMenuItem);changeJMenu.add(animalJMenuItem);changeJMenu.add(sportJMenuItem);//将更换图片,重新游戏,重新登录,关闭游戏,存档,读档添加到“功能”选项当中functionJMenu.add(changeJMenu);functionJMenu.add(replayJMenuItem);functionJMenu.add(reLoginJMenuItem);functionJMenu.add(closeJMenuItem);functionJMenu.add(saveJMenu);functionJMenu.add(loadJMenu);//将公众号添加到关于我们当中aboutJMenu.add(accountJMenuItem);//给选项下面的条目添加监听girlJMenuItem.addActionListener(this);animalJMenuItem.addActionListener(this);sportJMenuItem.addActionListener(this);replayJMenuItem.addActionListener(this);reLoginJMenuItem.addActionListener(this);closeJMenuItem.addActionListener(this);accountJMenuItem.addActionListener(this);saveItem0.addActionListener(this);saveItem1.addActionListener(this);saveItem2.addActionListener(this);saveItem3.addActionListener(this);saveItem4.addActionListener(this);loadItem0.addActionListener(this);loadItem1.addActionListener(this);loadItem2.addActionListener(this);loadItem3.addActionListener(this);loadItem4.addActionListener(this);//将菜单里的两个选项添加到菜单当中jMenuBar.add(functionJMenu);jMenuBar.add(aboutJMenu);//读取存档信息,修改菜单上表示的内容getGameInfo();//给整个界面设置菜单this.setJMenuBar(jMenuBar);}public void getGameInfo(){//1.创建File对象表示所有存档所在的文件夹File file=new File("..\\puzzlegame\\save");//2.进入文件夹所获取到里面所有的存档文件File[] files=file.listFiles();//3.获取里面的部署,修改菜单for (File f : files) {//f :依次表示每一个存档文件//获取每一个存档文件中的步数GameInfo gi = null;try {ObjectInputStream ois=new ObjectInputStream(new FileInputStream(f));gi = (GameInfo) ois.readObject();ois.close();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}//获取到了步数int step=gi.getStep();//把存档的步数同步到菜单当中//save0 --->0//save1 ---> 1//...//获取存档的文件名 save0.dataString name= f.getName();//获取当前存档的序号(索引)int index=name.charAt(4)-'0';//修改菜单上所表示的文字信息saveJMenu.getItem(index).setText("存档"+index+"("+step+")步");loadJMenu.getItem(index).setText("存档"+index+"("+step+")步");}}//初始化界面private void initJFrame() {//设置界面的宽高this.setSize(603,680);//设置界面的标题this.setTitle("拼图单机版 v1.0");//设置界面置顶this.setAlwaysOnTop(true);//设置界面居中显示this.setLocationRelativeTo(null);//设置关闭模式this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,而是采用绝对定位的方式this.setLayout(null);//给整个界面添加键盘的监听this.addKeyListener(this);}@Overridepublic void keyTyped(KeyEvent e) {}//按下不松时,会一直触发该方法@Overridepublic void keyPressed(KeyEvent e) {int code = e.getKeyCode();if(code == 65){//把界面中的图片全部删除this.getContentPane().removeAll();//加载第一张完整的图片JLabel jLabel = new JLabel(new ImageIcon(path+"all.jpg"));jLabel.setBounds(83,134,420,420);//把图片添加到界面中this.getContentPane().add(jLabel);//加载背景图片JLabel background = new JLabel(new ImageIcon("..\\puzzlegame\\image\\background.png"));background.setBounds(40,40,520,600);//把背景图片添加到界面中this.getContentPane().add(background);//刷新界面this.getContentPane().repaint();}}//松开按键时,触发该方法@Overridepublic void keyReleased(KeyEvent e) {//判断游戏是否胜利,如果胜利了,就不再接收键盘的输入了if(victory()){return;}//对上,下,左,右四个方向键进行判断//左:37 上:38 右:39 下:40int code = e.getKeyCode();if(code == 37){//左if(y == 3){//如果空白方块已经在最左边了,就不能再往左移动了return;}System.out.println("向左移动");data[x][y] = data[x][y+1];data[x][y+1] = 0;y++;step++;//重新加载图片initImage();}else if(code == 38){//上if(x == 3){//如果空白方块已经在最上面了,就不能再往上移动了return;}System.out.println("向上移动");data[x][y] = data[x+1][y];data[x+1][y] = 0;x++;step++;//重新加载图片initImage();}else if(code == 39){//右if(y == 0){//如果空白方块已经在最右边了,就不能再往右移动了return;}System.out.println("向右移动");data[x][y] = data[x][y-1];data[x][y-1] = 0;y--;step++;//重新加载图片initImage();}else if(code == 40){//下if(x == 0){//如果空白方块已经在最下面了,就不能再往下移动了return;}System.out.println("向下移动");data[x][y] = data[x-1][y];data[x-1][y] = 0;x--;step++;//重新加载图片initImage();}else if(code == 65){initImage();}else if(code == 87){data=new int [][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};initImage();}}//判断是否胜利public boolean victory(){for (int i = 0; i < data.length; i++) {for (int j = 0; j < data[i].length; j++) {if(data[i][j] != win[i][j]){return false;}}}return true;}@Overridepublic void actionPerformed(ActionEvent e) {//获取到当前点击的条目对象Object obj = e.getSource();if(obj == replayJMenuItem){System.out.println("重新游戏");//计步器清零step = 0;//重新打乱图片的顺序initData();//重新加载图片initImage();}else if(obj == reLoginJMenuItem){System.out.println("重新登录");//关闭当前的游戏界面this.setVisible(false);//打开登录界面new LoginJFrame();}else if(obj == closeJMenuItem){System.out.println("关闭游戏");System.exit(0);}else if(obj == accountJMenuItem){System.out.println("公众号");//1.创建集合Properties prop=new Properties();//2.读取数据try {FileInputStream fis=new FileInputStream("..\\puzzlegame\\game.properties");prop.load(fis);fis.close();} catch (IOException ex) {throw new RuntimeException(ex);}//3.获取图片的路径String path=(String)prop.get("account");//调用下面的showIDialog方法,展示弹框//showJDialog方法的参数,就是图片的路径//比如:showJDialog("puzzlegame\\image\\about1.png");showJDialog(path);}else if(obj == girlJMenuItem){System.out.println("美女");Random r=new Random();int i;if(flag==0){i=r.nextInt(13)+1;}else{i=r.nextInt(3)+14;}path="..\\puzzlegame\\image\\girl\\girl"+i+"\\";step=0;initData();initImage();}else if(obj == animalJMenuItem){System.out.println("动物");Random r=new Random();int i=r.nextInt(8)+1;path="..\\puzzlegame\\image\\animal\\animal"+i+"\\";step=0;initData();initImage();}else if(obj == sportJMenuItem){System.out.println("运动");Random r=new Random();int i=r.nextInt(10)+1;path="..\\puzzlegame\\image\\sport\\sport"+i+"\\";//计步器清零step=0;//再次打乱二维数组中的数据initData();//重新加载图片initImage();}else if (obj==saveItem0||obj==saveItem1||obj==saveItem2||obj==saveItem3||obj==saveItem4){//获取当前是哪个存档被点击了,获取其中的序号JMenuItem item=(JMenuItem) obj;String str=item.getText();int index=str.charAt(2)-'0';//之间把游戏的数据写到本地文件中try {ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\puzzlegame\\save\\save"+index+".data"));GameInfo gi=new GameInfo(data,x,y,path,step);oos.writeObject(gi);oos.close();} catch (IOException ioException) {ioException.printStackTrace();}//修改一下存档item上的展示信息//存档0(xx步)item.setText("存档"+index+"("+step+"步)");//修改一下读档item上的展示信息loadJMenu.getItem(index).setText("存档"+index+"("+step+"步)");}else if (obj==loadItem0||obj==loadItem1||obj==loadItem2||obj==loadItem3||obj==loadItem4){System.out.println("读档");//获取当前是哪个读档被点击了,获取其中的序号JMenuItem item=(JMenuItem) obj;String str=item.getText();int index=str.charAt(2)-'0';//可以到本地文件中读取数据GameInfo gi=null;try {ObjectInputStream ois=new ObjectInputStream(new FileInputStream("..\\puzzlegame\\save\\save"+index+".data"));gi=(GameInfo)ois.readObject();ois.close();} catch (IOException ioException) {ioException.printStackTrace();} catch (ClassNotFoundException classNotFoundException) {classNotFoundException.printStackTrace();}data=gi.getData();path=gi.getPath();step=gi.getStep();x=gi.getX();y=gi.getY();//重新刷新界面并加载游戏initImage();;}}//创建一个弹框对象JDialog jDialog = new JDialog();//展示弹框public void showJDialog(String filepath) {if (!jDialog.isVisible()) {JLabel jLabel = null;//判断传递的字符串是否是一个路径,且必须以jpg或者png结尾//如果满足,则当做图片处理//如果不满足,则当做普通字符串处理if (new File(filepath).exists() && (filepath.endsWith(".png") || filepath.endsWith(".jpg"))) {jLabel = new JLabel(new ImageIcon(filepath));} else {jLabel = new JLabel(filepath);}//设置位置和宽高jLabel.setBounds(0, 0, 258, 258);//把图片添加到弹框当中jDialog.getContentPane().add(jLabel);//给弹框设置大小jDialog.setSize(344, 344);//让弹框置顶jDialog.setAlwaysOnTop(true);//让弹框居中jDialog.setLocationRelativeTo(null);//弹框不关闭则无法操作下面的界面jDialog.setModal(true);//让弹框显示出来jDialog.setVisible(true);}}
}
登录界面
package ui;import cn.hutool.core.io.FileUtil;
import domain.User;
import util.CodeUtil;import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class LoginJFrame extends JFrame implements MouseListener
{//表示登录界面//创建一个集合存储正确的用户名和密码ArrayList<User> allUsers=new ArrayList<>();//登录和注册JButton login = new JButton();JButton register = new JButton();//创建文本框对象JTextField username = new JTextField();JPasswordField password = new JPasswordField();JTextField code = new JTextField();//正确的验证码JLabel rightCode=new JLabel();public LoginJFrame(){//读取本地文件中的用户信息readUserInfo();//初始化界面initJFramed();//初始化页面initView();//让界面显示出来this.setVisible(true);}//读取本地文件中的用户信息private void readUserInfo() {//1.读取数据List<String> userInfoStrList = FileUtil.readUtf8Lines("D:\\idea代码\\untitled1\\puzzlegame\\userinfo.txt");//2.遍历集合并获取用户信息并创建User对象for (String str : userInfoStrList) {String[] userInfoArr=str.split("&");System.out.println(Arrays.toString(userInfoArr));String[] arr1 = userInfoArr[0].split("=");String[] arr2 = userInfoArr[1].split("=");User u=new User(arr1[1],arr2[1]);allUsers.add(u);}System.out.println(allUsers);}//初始化页面private void initView() {//1.添加用户名文字JLabel usernameText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\login\\用户名.png"));usernameText.setBounds(116,135,47,17);this.getContentPane().add(usernameText);//2.添加用户名输入框username.setBounds(195,134,200,30);this.getContentPane().add(username);//3.添加密码文字JLabel passwordText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\login\\密码.png"));passwordText.setBounds(130,195,32,16);this.getContentPane().add(passwordText);//4.添加密码输入框password.setBounds(195,194,200,30);this.getContentPane().add(password);//5.添加验证码文字JLabel codeText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\login\\验证码.png"));codeText.setBounds(133,256,50,30);this.getContentPane().add(codeText);//6.添加验证码输入框code.setBounds(195,256,100,30);this.getContentPane().add(code);//随机生成一个验证码String codeStr= CodeUtil.getCode();System.out.println(codeStr);//设置内容rightCode.setText(codeStr);//位置和宽高rightCode.setBounds(300,256,50,30);//添加鼠标监听事件rightCode.addMouseListener(this);//添加到桌面this.getContentPane().add(rightCode);//7.添加登录按钮login.setBounds(123,310,128,47);login.setIcon(new ImageIcon("..\\puzzlegame\\image\\login\\登录按钮.png"));//去除按钮的边框login.setBorderPainted(false);//去除按钮的背景login.setContentAreaFilled(false);//添加鼠标监听事件login.addMouseListener(this);this.getContentPane().add(login);//8.添加注册按钮register.setBounds(256,310,128,47);register.setIcon(new ImageIcon("..\\puzzlegame\\image\\login\\注册按钮.png"));//去除按钮的边框register.setBorderPainted(false);//去除按钮的背景register.setContentAreaFilled(false);//添加鼠标监听事件register.addMouseListener(this);this.getContentPane().add(register);//7.添加背景图片JLabel background = new JLabel(new ImageIcon("..\\puzzlegame\\image\\login\\background.png"));background.setBounds(0,0,470,390);this.getContentPane().add(background);}//初始化界面private void initJFramed() {//在创建登录界面的时候,同时给这个界面去设置一些信息this.setSize(488,430);//设置界面的标题this.setTitle("拼图 登录");//设置界面置顶this.setAlwaysOnTop(true);//设置界面居中显示this.setLocationRelativeTo(null);//设置关闭模式this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,而是采用绝对定位的方式this.setLayout(null);}//设置弹窗public void showJDialog(String content){//创建一个弹框对象JDialog jDialog=new JDialog();//给弹框设置大小jDialog.setSize(200,150);//设置弹框置顶jDialog.setAlwaysOnTop(true);//设置弹框居中显示jDialog.setLocationRelativeTo(null);//设置弹框不关闭永远无法操作下面的界面jDialog.setModal(true);//创建JLabel对象管理文字并添加到弹框当中JLabel warning=new JLabel(content);warning.setBounds(0,0,200,150);jDialog.getContentPane().add(warning);//让弹框显示出来jDialog.setVisible(true);}//鼠标按下并释放事件@Overridepublic void mouseClicked(MouseEvent e) {if (e.getSource() == login) {System.out.println("点击了登录按钮");//获取两个文本输入框中的内容String usernameInput = username.getText();String passwordInput = password.getText();//获取用户输入的验证码String codeInput = code.getText();//创建一个User对象User userInfo = new User(usernameInput, passwordInput);System.out.println("用户输入的用户名为" + usernameInput);System.out.println("用户输入的密码为" + passwordInput);if (codeInput.length() == 0) {showJDialog("验证码不能为空");} else if (usernameInput.length() == 0 || passwordInput.length() == 0) {//校验用户名和密码是否为空System.out.println("用户名或者密码为空");//调用showJDialog方法并展示弹框showJDialog("用户名或者密码为空");} else if (!codeInput.equalsIgnoreCase(rightCode.getText())) {showJDialog("验证码输入错误");} else if (contains(userInfo)) {System.out.println("用户名和密码正确可以开始玩游戏了");//关闭当前登录界面this.setVisible(false);//打开游戏的主界面//需要把当前登录的用户名传递给游戏界面if(usernameInput.equals("yangyuchan")){new GameJFrame(1);}else {new GameJFrame(0);}} else {System.out.println("用户名或密码错误");showJDialog("用户名或密码错误");}login.setBounds(123,310,128,47);login.setIcon(new ImageIcon("..\\puzzlegame\\image\\login\\登录按钮.png"));} else if (e.getSource() == register) {System.out.println("点击了注册按钮");//关闭当前的登录界面this.setVisible(false);//打开注册界面new RegisterJFrame(allUsers);} else if (e.getSource() == rightCode) {System.out.println("更换验证码");//获取一个新的验证码String code = CodeUtil.getCode();rightCode.setText(code);}}//鼠标按下事件@Overridepublic void mousePressed(MouseEvent e) {if(e.getSource()==login){System.out.println("登录按钮被按下了");login.setIcon(new ImageIcon("puzzlegame\\image\\login\\登录按下.png"));} else if (e.getSource()==register) {System.out.println("注册按钮被按下了");register.setIcon(new ImageIcon("puzzlegame\\image\\login\\注册按下.png"));}}//鼠标释放事件@Overridepublic void mouseReleased(MouseEvent e) {if (e.getSource() == login) {login.setIcon(new ImageIcon("puzzlegame\\image\\login\\登录按钮.png"));} else if (e.getSource() == register) {register.setIcon(new ImageIcon("puzzlegame\\image\\login\\注册按钮.png"));}}//鼠标进入事件@Overridepublic void mouseEntered(MouseEvent e) {}//鼠标离开事件@Overridepublic void mouseExited(MouseEvent e) {}//判断用户在集合中是否存在public boolean contains(User userInput){for (int i = 0; i < allUsers.size(); i++) {User rightUser=allUsers.get(i);if(userInput.getUsername().equals(rightUser.getUsername())&&userInput.getPassword().equals(rightUser.getPassword())){//有相同的代表存在,返回true,后面的不需要再比了return true;}}//混合结束之后还没有找到就表示不存在return false;}
}
注册界面
package ui;import cn.hutool.core.io.FileUtil;
import domain.User;import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;public class RegisterJFrame extends JFrame implements MouseListener{//表示注册的界面ArrayList<User> allUsers;//提升三个输入框的变量的作用范围,让这三个变量可以在本类中所有方法里面可以使用。JTextField username = new JTextField();JTextField password = new JTextField();JTextField rePassword = new JTextField();//提升两个按钮变量的作用范围,让这两个变量可以在本类中所有方法里面可以使用。JButton submit = new JButton();JButton reset = new JButton();public RegisterJFrame(ArrayList<User> allUsers){this.allUsers=allUsers;//初始化界面initFrame();initView();//让界面显示出来this.setVisible(true);}private void initView() {//添加注册用户名的文本JLabel usernameText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\register\\注册用户名.png"));usernameText.setBounds(85, 135, 80, 20);//添加注册用户名的输入框username.setBounds(195, 134, 200, 30);//添加注册密码的文本JLabel passwordText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\register\\注册密码.png"));passwordText.setBounds(97, 193, 70, 20);//添加密码输入框password.setBounds(195, 195, 200, 30);//添加再次输入密码的文本JLabel rePasswordText = new JLabel(new ImageIcon("..\\puzzlegame\\image\\register\\再次输入密码.png"));rePasswordText.setBounds(64, 255, 95, 20);//添加再次输入密码的输入框rePassword.setBounds(195, 255, 200, 30);//注册的按钮submit.setIcon(new ImageIcon("..\\puzzlegame\\image\\register\\注册按钮.png"));submit.setBounds(123, 310, 128, 47);submit.setBorderPainted(false);submit.setContentAreaFilled(false);submit.addMouseListener(this);//重置的按钮reset.setIcon(new ImageIcon("..\\puzzlegame\\image\\register\\重置按钮.png"));reset.setBounds(256, 310, 128, 47);reset.setBorderPainted(false);reset.setContentAreaFilled(false);reset.addMouseListener(this);//背景图片JLabel background = new JLabel(new ImageIcon("..\\puzzlegame\\image\\register\\background.png"));background.setBounds(0, 0, 470, 390);this.getContentPane().add(usernameText);this.getContentPane().add(passwordText);this.getContentPane().add(rePasswordText);this.getContentPane().add(username);this.getContentPane().add(password);this.getContentPane().add(rePassword);this.getContentPane().add(submit);this.getContentPane().add(reset);this.getContentPane().add(background);}private void initFrame() {//对自己的界面做一些设置。//设置宽高setSize(488, 430);//设置标题setTitle("拼图游戏 V1.0注册");//取消内部默认布局setLayout(null);//设置关闭模式setDefaultCloseOperation(3);//设置居中setLocationRelativeTo(null);//设置置顶setAlwaysOnTop(true);}//只创建一个弹框对象JDialog jDialog = new JDialog();//因为展示弹框的代码,会被运行多次//所以,我们把展示弹框的代码,抽取到一个方法中。以后用到的时候,就不需要写了//直接调用就可以了。public void showDialog(String content) {if (!jDialog.isVisible()) {//把弹框中原来的文字给清空掉。jDialog.getContentPane().removeAll();JLabel jLabel = new JLabel(content);jLabel.setBounds(0, 0, 200, 150);jDialog.add(jLabel);//给弹框设置大小jDialog.setSize(200, 150);//要把弹框在设置为顶层 -- 置顶效果jDialog.setAlwaysOnTop(true);//要让jDialog居中jDialog.setLocationRelativeTo(null);//让弹框jDialog.setModal(true);//让jDialog显示出来jDialog.setVisible(true);}}@Overridepublic void mouseClicked(MouseEvent e) {if(e.getSource()==submit){//点击了注册按钮//1.用户名,密码不能为空if(username.getText().length()==0||password.getText().length()==0||rePassword.getText().length()==0){showDialog("用户名和密码不能为空");return;}//2.判断两次密码输入是否一致if(!password.getText().equals(rePassword.getText())){showDialog("两次密码输入不一致");return;}//3.判断用户名和密码1的格式是否正确if(!username.getText().matches("[a-zA-Z0-9]{4,16}")){showDialog("用户名必须是4~16位的数字或字母");return;}if(!password.getText().matches("\\S*(?=\\S{6,})(?=\\S*\\d)(?=\\S*[a-z])\\S*")){showDialog("密码不符合规则,至少包含1个小写字母,1个数字,长度至少6位");return;}//4.判断用户名是否已经重复if(containsUsername(username.getText())){showDialog("用户名已经存在,请重新输入");return;}//5.添加用户allUsers.add(new User(username.getText(),password.getText()));//6.写入文件FileUtil.writeLines(allUsers,"D:\\idea代码\\untitled1\\puzzlegame\\userinfo.txt","UTF-8");//7.提示注册成功showDialog("注册成功");//关闭注册界面,打开登录界面this.setVisible(false);new LoginJFrame();}else if(e.getSource()==reset){//点击了重置按钮//清空了三个输入框username.setText("");password.setText("");rePassword.setText("");}}/*作用:参数:判断username在集合中是否存在用户名返回值:true:存在false:不存在*/public boolean containsUsername(String username){for (User u : allUsers) {if (u.getUsername().equals(username)){return true;}}return false;}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}}
验证码生成
package util;import java.util.Random;public final class CodeUtil {private CodeUtil(){}public static String getCode(){//a-97 A-65char []str=new char[52];for (int i = 0; i < str.length; i++) {if(i<=25){str[i]=(char)(i+65);}else{str[i]=(char)(i+71);}}StringBuilder sb=new StringBuilder();Random random=new Random();String code="";for (int i = 0; i < 4; i++) {int index = random.nextInt(str.length);code+=str[index];}code+=(random.nextInt(10));char[] chars = code.toCharArray();int index = random.nextInt(chars.length);char temp = chars[4];chars[4] = chars[index];chars[index] = temp;String result = new String(chars);return result;}
}
用户类
package domain;public class User {private String username;private String password;public User() {}public User(String username, String password) {this.username = username;this.password = password;}/*** 获取** @return username*/public String getUsername() {return username;}/*** 设置** @param username*/public void setUsername(String username) {this.username = username;}/*** 获取** @return password*/public String getPassword() {return password;}/*** 设置** @param password*/public void setPassword(String password) {this.password = password;}public String toString() {return "username=" + username + "&password=" + password;}
}
游戏信息类
package domain;import java.io.Serial;
import java.io.Serializable;public class GameInfo implements Serializable {@Serialprivate static final long serialVersionUID = -5313750424022850690L;private int[][] data;private int x=0;private int y=0;private String path;private int step;public GameInfo() {}public GameInfo(int[][] data, int x, int y, String path, int step) {this.data = data;this.x = x;this.y = y;this.path = path;this.step = step;}/*** 获取* @return data*/public int[][] getData() {return data;}/*** 设置* @param data*/public void setData(int[][] data) {this.data = data;}/*** 获取* @return x*/public int getX() {return x;}/*** 设置* @param x*/public void setX(int x) {this.x = x;}/*** 获取* @return y*/public int getY() {return y;}/*** 设置* @param y*/public void setY(int y) {this.y = y;}/*** 获取* @return path*/public String getPath() {return path;}/*** 设置* @param path*/public void setPath(String path) {this.path = path;}/*** 获取* @return step*/public int getStep() {return step;}/*** 设置* @param step*/public void setStep(int step) {this.step = step;}public String toString() {return "GameInfo{data = " + data + ", x = " + x + ", y = " + y + ", path = " + path + ", step = " + step + "}";}
}