IO流(下)
五、File类
流操作的是数据,而数据最常见的体现形式就是文件,而文件又包含大量的属性信息,并且文件的对象非常多,所以java语言对文件进行了描述,即File类。
流只能操作文件,不能操作文件夹;File类将文件或者文件夹封装成对象,方便对于文件或文件夹属性信息进行操作,并且File对象可以作为参数传递给流的构造函数,使用非常方便。
File类常见的方法:
1、创建:
boolean createNewFile():在指定位置创建文件,已存在则不创建,返回false,输出流对象一建立就创建文件,并且文件存在则覆盖。
boolean mkdir():创建文件夹;
boolean mkdirs():创建多级文件夹。
2、删除:
boolean delete():删除失败返回false;
void deleteOnExit():在程序退出时删除指定文件。
3、判断:
boolean exists():文件是否存在;注意:在操作之前必须判断文件是否存在;
boolean isFile():是否是文件;
boolean isDirectory():是否是目录;
boolean isHidden():是否隐藏;
boolean isAbsolute():是否是绝对路径;
4、获取信息:
getName():获取名称;
getPath():获取路径;
getParent():获取父目录;
getAbsolutePath():获取绝对路径;
long length():获取长度;
listRoots():根目录;
list():获取文件列表;调用该方法之前,必须保证file对象封装了一个目录,存在;
递归:函数自己调用自己,称为递归;递归注意:1、限定条件,2、递归次数不能过大,避免内存溢出。
下面代码体现:
1、File类常用方法的简单演示:
1.1:
package itheima.day20;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) {
// consMethod();
// method_1();
// method_3();
method_4();
}
// 2、创建
public static void method_1(){
File f = new File("file.txt");
try {
sop("create:"+f.createNewFile());
} catch (IOException e) {
throw new RuntimeException("文件创建异常!");
}
// 删除,删除失败,返回false
sop("delete::"+f.delete());
// 在程序退出时删除指定文件
f.deleteOnExit();
}
// 判断
public static void method_2(){
File f = new File("file2.txt");
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
// 判断文件是否可执行
sop("canExcute:"+f.canExecute());
sop("exists:"+f.exists());
File dir = new File("abc\\aa\\bb\\cc\\dd\\ee");
// 创建文件夹,多层目录
sop("mkdirs:"+dir.mkdirs());
}
public static void method_3(){
// 只是封装成一个文件对象而已,未创建
File f = new File("file3.txt");
// 对一个File对象判断是文件或者目录之前,必须判断它是否存在
sop("exist"+f.exists());
sop("dir:"+f.isDirectory());
sop("File:"+f.isFile());
}
// 获取
public static void method_4(){
File f = new File("abc\\a.txt");
// 获取封装的路径
sop("path:"+f.getPath());
// 获取绝对路径
sop("abspath:"+f.getAbsolutePath());
// 获取父目录
sop("parent:"+f.getParent());
}
public static void method_5(){
File f1= new File("c:\\Test.java");
File f2= new File("c:\\hahaha.java");
// 剪切
sop("rename:"+f1.renameTo(f2));
}
// 1、创建File对象
public static void consMethod(){
// 将a.txt封装成为对象,可以将已有的和未出现的文件或者文件夹封装成为对象
File f1 = new File("ss.txt");
// File.separator:与系统有关的分隔符;父目录+文件名
File f2 = new File("c:"+File.separator+"abc","b.txt");
// 把目录封装成为File
File d = new File("c:"+File.separator+"abc");
File f3 = new File(d,"c.txt");
sop("f1:::"+f1);
sop("f2:::"+f2);
sop("f3:::"+f3);
}
public static void sop(Object obj){
System.out.println(obj);
}
}
1.2:package itheima.day20;
import java.io.File;
import java.io.FilenameFilter;
public class FileDemo2 {
public static void main(String[] args) {
// listRootsDemo();
// listDemo();
listDemo_3();
// listDemo_2();
}
public static void listRootsDemo(){
// C:\;D:\;E:\;F:\;G:\ 机器里面的有效盘符
File[] files = File.listRoots();
for(File f:files){
System.out.println(f);
}
}
public static void listDemo(){
File f = new File("c:\\");
// 获取目录的列表,包含隐藏文件
String[] names = f.list();
for(String name:names){
System.out.println(name);
}
}
public static void listDemo_2(){
File dir = new File("c:\\");
String [] arr = dir.list(new FilenameFilter(){
// 文件名过滤器
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".txt");
}
});
for(String name:arr){
System.out.println(name);
}
}
public static void listDemo_3(){
File dir = new File("c:\\");
// 文件列表
File[] files = dir.listFiles();
for(File f:files){
System.out.println(f.getName()+"::::"+f.length());
}
}
}
2、列出指定目录下文件或者文件夹,包含目录中的内容:
package itheima.day20;
import java.io.File;
//列出指定目录下文件或者文件夹,包含目录中的内容
//也就是列出指定目录下所有内容
public class FileDemo3 {
public static void main(String[] args) {
File dir = new File("D:\\java\\workspace1\\JavaFoundation");
showDir(dir,0);
}
public static void showDir(File dir,int level){
System.out.println(getLevel(level)+dir.getName());
level++;
File[] files = dir.listFiles();
for(int x =0;x<files.length;x++){
if(files[x].isDirectory())
showDir(files[x],level);
else
System.out.println(getLevel(level)+files[x]);
}
}
public static String getLevel(int level){
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int x =0; x<level;x++){
// sb.append("|--");
sb.insert(0, "| ");
}
return sb.toString();
}
}
3、删除一个带内容的目录:
package itheima.day20;
import java.io.File;
//删除一个带内容的目录
// 删除原理:从里往外删
public class RemoveDir {
public static void main(String[] args) {
File dir = new File("d:\\Test");
removeDir(dir);
}
public static void removeDir(File dir){
File[] files = dir.listFiles();
for(int x=0;x<files.length;x++){
if(files[x].isDirectory()/* && !files[x].isHidden()*/)
removeDir(files[x]);
else
System.out.println(files[x].toString()+"----"+files[x].delete());
}
System.out.println(dir+"::dir::"+dir.delete());
}
}
4、将一个指定目录下的java文件的绝对路径,存储到一个文本文件中:
package itheima.day20;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*将一个指定目录下的java文件的绝对路径,存储到一个文本文件中,
* 建立一个java文件列表文件。
* 思路:1、对指定的目录进行递归;
* 2、获取递归过程中的java文件路径
* 3、将这些路径存储到集合中
* 4、将集合中的数据写入到一个文件中。
* */
public class JavaFileList {
public static void main(String[] args) {
File dir = new File("d:\\java\\workspace1\\Test");
List<File> list = new ArrayList<File>();
fileToList(dir,list);
File file = new File("javalist.txt");
writeToFile(list,file.toString());
Iterator<File> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
public static void fileToList(File dir,List<File> list){
File[] files = dir.listFiles();
for(File file:files){
if(file.isDirectory())
fileToList(file,list);
else{
if(file.getName().endsWith(".java"))
list.add(file);
}
}
}
public static void writeToFile(List<File> list, String javaListFile){
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(javaListFile));
for(File f:list){
String path = f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
} catch (IOException e) {
throw new RuntimeException("IO读写异常!");
}finally{
try {
if(bufw!=null)
bufw.close();
} catch (IOException e) {
throw new RuntimeException("文件关闭异常!");
}
}
}
}
六、Properties类:
Properties是hashtable的子类,它具备map集合的特点,并且它里面存储的键值对都是字符串的形式;Properties是集合中和IO技术相结合的容器,该类对象的特点:可以用来存储键值对形式的配置文件,那么加载数据时,需要数据有固定的格式,键=值。
5.0:properties类常用方法的演示:
package itheima.day20;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo {
public static void main(String[] args) {
// setAndGet();
method_1();
// loadDemo();
}
public static void loadDemo(){
Properties prop = new Properties();
try {
FileInputStream fis = new FileInputStream("info.txt");
prop.load(fis);
// System.out.println(prop);
// 调用Hashtable中的put方法,改变Property中的属性
prop.setProperty("wangwu", "15");
FileOutputStream fos = new FileOutputStream("info.txt");
// 存到一个流中,然后存到文件中,持久化
prop.store(fos, "heihei");//注释
prop.list(System.out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 演示如何将流中的数据存储到集合中,想要将info.txt中键值数据存到集合中进行操作。
// 思路:1、用一个流和info.txt文件关联
// 2、读取一行数据,将该行数据用"="进行切割
// 3、等号左边作为建,右边作为值,存入到Properties中
public static void method_1(){
BufferedReader bufr = null;
try {
bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
Properties prop = new Properties();
while((line = bufr.readLine())!=null){
// System.out.println(line);
String[] arr = line.split("=");
prop.setProperty(arr[0], arr[1]);
}
System.out.println(prop);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bufr!=null)
bufr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 设置和获取元素
public static void setAndGet(){
Properties prop = new Properties();
// 底层调用的是Hashtable的put方法
prop.setProperty("zhangsan1", "30");
prop.setProperty("zhangsan2", "20");
// 把map转成Set,再取
Set<String> names= prop.stringPropertyNames();
for(String s: names){
System.out.println(s+":"+prop.getProperty(s));
}
}
}
5、写一个试用软件,如果使用次数已到,那么给出注册提示:
package itheima.day20;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
//用于记录应用程序运行次数,
// 如果使用次数已到,那么给出注册提示
//配置文件可以实现应用程序数据的共享
public class RunCount {
public static void main(String[] args)throws IOException {
Properties prop = new Properties();
File file = new File("count.ini");
// 文件不存在,则创建
if(!file.exists())
file.createNewFile();
FileInputStream fis = new FileInputStream(file);
// properties与输入流相关联
prop.load(fis);
int count = 0;
// 获取time属性的值
String value = prop.getProperty("time");
if(value !=null){
// 将值的字符串形式转成Integer
count = Integer.parseInt(value);
if(count>5){
throw new RuntimeException("哥们,您老人家的大寿已尽,请交钱!!!");
}
}
count++;
prop.setProperty("time", count+"");
FileOutputStream fos = new FileOutputStream(file);
// 把properties对象与输出流相关联,存储到指定文件中
prop.store(fos, "money");
fos.close();
fis.close();
}
}
七、IO中的其他类
7.1、序列流:SequenceInputStream:用于对多个流进行合并。
6、合并3个输入流为一个输入流:
package itheima.day20;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
//将多个流对象合并成一个流对象
public class SequenceDemo {
public static void main(String[] args) throws IOException {
Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
Enumeration<FileInputStream> en = v.elements();
// 该对象是JDK1.0时出现,合并流对象,输入流
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("4.txt");
byte[] buf = new byte[1024];
int len =0;
while((len = sis.read(buf)) != -1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
7、切割一个mp3文件:
package itheima.day20;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
//切割文件
public class SplitFileDemo {
public static void main(String[] args) throws IOException {
splitFile();
merge();
}
// 切割
public static void splitFile() throws IOException{
FileInputStream fis = new FileInputStream("1.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count =1;
while((len = fis.read(buf)) != -1){
// 产生一个文件
fos = new FileOutputStream((count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
// 合并文件
public static void merge() throws IOException{
// 把这些流对象存到一个ArrayList集合中
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int i=1;i<6;i++){
al.add(new FileInputStream(i+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
// 匿名内部类,不能访问外部类的局部变量
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public FileInputStream nextElement() {
return it.next();
}
};
// 构造函数为一个Enumeration对象,合并这些流
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("2.mp3");
byte[] buf = new byte[1024];
int len =0;
while((len =sis.read(buf))!=-1){
fos.write(buf, 0, len);
fos.flush();
}
fos.close();
sis.close();
}
}
7.2、管道流:PipedInputStream和PipedOutputStream:可以合并两个流,涉及到多线程。
8、演示管道流:
package itheima.day21;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
//管道流
public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
// 链接
in.connect(out);
// 把管道输入流与管道输出流封装成线程的任务
Read r = new Read(in);
Write w = new Write(out);
// 线程启动
new Thread(r).start();
new Thread(w).start();
}
}
//读取的任务,封装到一个线程中
class Read implements Runnable{
private PipedInputStream in;
Read(PipedInputStream in){
this.in = in;
}
@Override
public void run() {
byte[] buf = new byte[1024];
try {
int len = in.read(buf);
String s = new String(buf,0,len);
System.out.println(s);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//写出的任务,封装到一个线程中
class Write implements Runnable{
private PipedOutputStream out;
Write(PipedOutputStream out){
this.out = out;
}
@Override
public void run() {
try {
out.write("lai le ,ge men ,heihei ".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
7.3、RandomAccessFile:随机访问,自身具备读写方法,通过skipBytes(int x)和seek(int x)来实现随机访问。
7.4、PrintWriter和PrintStream:可以直接转换输入流和文件。
代码演示:
package itheima.day20;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
//凡是与流对象相关联的对象,都是比较重要的流对象
//打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印
//字节打印流:PrintStream
//构造函数可以接收的参数类型:
//1、file对象 File
//2、字符串路径 String
//3、字节输出流 OutputStream
//字符打印流 PrintWriter
//构造函数可以接收的类型:
//1、file对象 File
//2、字符串路径 String
//3、字节输出流 OutputStream
//4、字符输出流 Writer
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
// 字节流转换成字符流,并加入缓冲区技术
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
// 通用性极强,指定打印目的。并自动刷新,对write方法无效
PrintWriter out = new PrintWriter(System.out,true);
String line = null;
while((line = bufr.readLine())!=null){
if("over".equalsIgnoreCase(line))
break;
out.println(line.toUpperCase());
// out.write(line.toUpperCase());
}
out.close();
bufr.close();
}
}
7.5、ObjectInputStream和ObjectOutputStream:操作对象,但被操作的对象需要实现Serializable接口(一个标记接口,没有要覆盖的方法)。
代码演示:
package itheima.day21;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//直接操作对象的流
public class ObjectInputStreamDemo {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
writeObj();
readObj();
}
// 将对内存中的对象存到硬盘上
public static void writeObj() throws FileNotFoundException, IOException{
// 必须关联一个输出流
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("person.obj"));
oos.writeObject(new Person("lisi",45));
oos.close();
}
// 读取硬盘上存储的对象
public static void readObj() throws FileNotFoundException, IOException, ClassNotFoundException{
// 必须关联一个输入流
ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("person.obj"));
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
class Person implements Serializable
{
// 序列号是根据成员变量构造出来的
static final long serialVersionUID = 42L;//可以自己指定一个ID号
private String name;
private int age;//transient 不序列化
static public String country = "cn";
// 静态不能序列化,序列化只能是堆内存中的数据
Person(String name,int age ){
this.name = name;
this.age = age;
}
public String toString(){
return name+"::"+age+":::"+country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
7.6、DataInputStream和DataOutputStream:操作基本数据类型。
7.7、ByteArrayInputStream与ByteArrayOutputStream:操作字节数组;
CharArrayReader与CharArrayWriter :操作字符数组;
StringReader 与 StringWriter:操作字符串;
八、字符编码
字符流的出现是为了方便操作字符,字符流 = 字节流+编码;字符流是先获取到一定的字节,然后通过查阅相应的编码表,变成相应的字符,其实计算机中存储的是二进制形式的字节码。
InputStreamReader、OutputStreamWriter这两个转换流在字符流与字节流的转换时,可以指定特定的编码表,指定编码表的动作可以由构造函数完成,详情可以查阅API ,(UnsupportedEncodingException)。
编码表:计算机只能识别二进制数据,早期由来是电信号,为了方法计算机的使用,让它识别不同国家的文字,那么将各个国家的文字用特定的数字在计算机中表示,并一一对应,形成了一张映射表,这张现实生活中的文字与计算机中二进制数据一一对应的映射表,称为编码表。
常见编码表:
1、ASCII:美国标准信息交换码,用一个字节的7位表示;
2、ISO8859-1:拉丁码表,欧洲码表;用一个字节的8位表示;
3、GBK2312:中国的中文编码表;
4、GBK:中国的中文编码升级版,融合了更多的中文文字符号,两个字节表示;
5、Unicode:国际标准码,融合了多种文字,两个字节表示;
6、UTF-8:可以理解为Unicode的优化版,最多用三个字节表示一个字符。
编码:字符串-->字节数组:String-->byte[] s.getBytes(charsetName);
解码:字节数组-->字符串:Byte[]-->String new String(byte[],charsetName);
当发生乱码时,可以先解码,然后再重新编码即可。例如:将一个中文用gbk编码,用iso8859-1解码,乱码;解决方式:对乱码进行iso8859-1编码,再用gbk解码即可。
但:用gbk编码,用utf-8解码,乱码,再用utf-8编码,用gbk解码还是乱码。这是因为:用gbk编码后的数字去查utf-8的码表时utf-8不识别,就直接用一个未知字符来表示,而这个未知字符是3个字节的;原数字码已经变化了,所以还原不回来,乱码。
9、编码演示1:
package itheima.day21;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class EncodeDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "你好";
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));//[-60, -29, -70, -61]
String s1 = new String(b1,"GBK");
System.out.println("s1 = "+s1);//s1 = 你好
byte[] b2 = s.getBytes("UTF-8");
System.out.println(Arrays.toString(b2));//[-28, -67, -96, -27, -91, -67]
String s2 = new String(b2,"UTF-8");
System.out.println("s2 = "+s2);//s2 = 你好
// ”联通“的GBK编码正好符合了UTF-8的解码形式
String ss = "联通";//u8加有自己的标识头
byte[] by = ss.getBytes("gbk");
for(byte b:by){
System.out.println(Integer.toBinaryString(b&255));
}
}
}
10、编码演示2:
package itheima.day21;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
public class EncodeStream {
public static void main(String[] args) throws IOException {
writeText();
readText();
}
public static void writeText() throws IOException{
// 转换流可以指定编码表
OutputStreamWriter osw =
new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
public static void readText() throws IOException{
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"GBK");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
}
11、综合练习一枚:
package itheima.day21;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
/*有五个学生,每个学生有3们课的成绩,从键盘输入以上数据(姓名,成绩)
* 输入格式:zs,56,48,59计算出总成绩
* 并把学生的信息和计算出的总分按高低顺序存放在磁盘文件"stud.txt"中。
* */
/*1、描述学生对象
* 2、定义一个可操作学生对象的工具类
* 思想:
* 1、通过获取键盘录入一行数据,并将该行中的信息取出封装成为学生对象
* 2、因为学生有很多,那么就需要存储,使用集合,要排序,TreeSet
* 3、将集合中的信息写入到一个文件中
* */
public class StudentInfoTest {
public static void main(String[] args) throws IOException {
Comparator<Student> cmp = Collections.reverseOrder();
Set<Student> stus = StudentInfoTool.getStudents(cmp);
StudentInfoTool.write2File(stus);
}
}
class Student implements Comparable<Student>
{
private String name;
private int math,chinese,english;
private int sum;
Student(String name,int math,int chinese,int english){
this.name = name;
this.math = math;
this.chinese = chinese;
this.english = english;
this.sum = math+chinese+english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
@Override
public int hashCode() {
return name.hashCode()+sum*23;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配异常");
Student stu = (Student)obj;
return this.name.equals(stu.name) && (this.sum == stu.sum);
}
@Override
public String toString() {
return "Student [name=" + name + ", math=" + math + ", chinese="
+ chinese + ", english=" + english + ", sum=" + sum + "]";
}
@Override
public int compareTo(Student o) {
int num = this.sum - o.sum;
if(num==0)
return this.name.compareTo(o.name);
return num;
}
}
class StudentInfoTool
{
public static Set<Student> getStudents() throws IOException{
return getStudents(null);
}
public static Set<Student> getStudents(Comparator<Student> cmp) throws IOException{
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
Set<Student> stus = null;
if(cmp==null)
stus = new TreeSet<Student>();
else
stus =new TreeSet<Student>(cmp);
while((line = bufr.readLine()) !=null){
if("over".equals(line))
break;
String[] info = line.split(",");
Student stu = new Student(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
public static void write2File(Set<Student> stus) throws IOException{
BufferedWriter bufw= new BufferedWriter(new FileWriter("student.txt"));
for(Student stu:stus){
bufw.write(stu.toString());
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}