JAVA作业8 输入输出流

8-1 写入日志文件

编写程序,要求:用户在键盘每输入一行文本,程序将这段文本显示在控制台中。当用户输入的一行文本是“exit”(不区分大小写)时,程序将用户所有输入的文本都写入到文件log.txt中,并退出。(要求:控制台输入通过流封装System.in获取,不要使用Scanner)


package test;

import java.io.*;
public class FileOperations {
     public static void main(String []args) {

		 String dirname="src/test/log.txt";

		 BufferedReader br=null;
		 BufferedWriter bw=null;
		try { 
			br=new BufferedReader(new InputStreamReader(System.in));//缓冲流
			bw=new BufferedWriter(new FileWriter(dirname));
		 while (true){
			 String s=br.readLine();
			 String ss=s.toUpperCase();

			 if(ss.equals("EXIT"))
				break;

			 System.out.println(s);
			 bw.write(s);
			 bw.newLine();//换行
		 }
		 bw.flush();
		 bw.close();
		}catch(Exception e){
			e.printStackTrace();
		}finally {
			try {
				br.close();

			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	 }
}




8-2 文件和目录输出

查看File类的API文档,使用该类实现一个类FileList,它提供两个静态方法:1)readContentsInDirectory(String path):能够将输入参数path所指定的本地磁盘路径下的所有目录和文件的名称打印出来;2)readContentsInDirectoryRecursive(String path):能够将输入参数path所指定的本地磁盘路径下的所有目录(包含所有子孙目录)和文件的名称以层次化结构打印出来。程序的输出如下所示。
在这里插入图片描述

package test;

import java.io.*;

public class FileList {
	public static void readContentsInDirectory(String path) {
		File file=new File(path);
		try {
			File[] files=file.listFiles();获取File对象的所有子文件和路径
			for(File i:files) {
				if(i.isFile()) {
					System.out.format("[文件] %s\n", i.getName());
				}else {
					System.out.format("[目录] %s\n", i.getName()	);
				}
			}
		}catch(Exception e) {
			System.out.println("路径不存在");
		}
	}
	public static void readContentsInDirectoryRecursive(String path,int levels) {
		File file=new File(path);
		try {
			File[] files=file.listFiles();获取File对象的所有子文件和路径
			for(File i:files) {
				for(int j=0;j<levels;j++) {
					System.out.print("--");
				}
				if(i.isFile()) {
					System.out.format("[文件] %s\n", i.getName());
			    }else {
			    	System.out.format("[目录] %s\n",i.getName());
			    	readContentsInDirectoryRecursive(i.getAbsolutePath(),levels+1);
			    }
		    }
		}catch(Exception e) {
	    	System.out.println("路径错误");
	    }
	}
}
package test;

import java.util.Scanner;
public class Main {
	public static void main(String []args)
	{
		Scanner cin=new Scanner(System.in);
		String path=cin.nextLine();
		FileList.readContentsInDirectory(path);
		System.out.println("----------------");//分割线
		FileList.readContentsInDirectoryRecursive(path, 0);
		cin.close();
	}
}

8-3 菜单文件处理

假设某个餐馆平时使用:1)文本文件(orders.txt)记录顾客的点菜信息,每桌顾客的点菜记录占一行。每行顾客点菜信息的记录格式是“菜名:数量,菜名:数量,…菜名:数量”。例如:“烤鸭:1,土豆丝:2,烤鱼:1”。2)文本文件(dishes.txt)记录每种菜的具体价格,每种菜及其价格占一行,记录格式为“菜名:价格“。例如:“烤鸭:169”。编写一个程序,能够计算出orders.txt中所有顾客消费的总价格。(注意,请使用文本读写流,及缓冲流来处理文件)

/*假设某个餐馆平时使用:1)文本文件(orders.txt)记录顾客的点菜信息,每桌顾客的点菜记录占一行。
每行顾客点菜信息的记录格式是“菜名:数量,菜名:数量,…菜名:数量”。
例如:“烤鸭:1,土豆丝:2,烤鱼:1”。
2)文本文件(dishes.txt)记录每种菜的具体价格,每种菜及其价格占一行,
记录格式为“菜名:价格“。例如:“烤鸭:169”。
编写一个程序,能够计算出orders.txt中所有顾客消费的总价格。
(注意,请使用文本读写流,及缓冲流来处理文件)*/

import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;

import java.io.*;
import java.util.*;
public class MenuFileOperations {
    public static void main(String[] args) throws FileNotFoundException{
        BufferedReader br1=null;//读
        //BufferedWriter bw1=null;//写
        BufferedReader br2=null;
        //BufferedWriter bw2=null;
        String path1="D:\\java\\Work8\\src\\orders.txt";//绝对路径
        String filename1="src\\orders.txt";// //相对路径(相对于项目工程为根目录)
        //File file1=new File(path1);
        // 使用Map记录菜名以及数量
        Map<String,Integer> orders=new HashMap<String, Integer>();

        try{//读入菜单
            br1=new BufferedReader(new InputStreamReader(new FileInputStream(filename1)));//创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
            //
           // bw1=new BufferedWriter(new FileWriter("scr/orders.txt"));

            String s=br1.readLine();//读一行文字。

            while(s!=null){
                String []s1=s.split(",");
                for (int i = 0; i <s1.length ; i++) {
                    String []s2=s1[i].split(":");
                    if(s2.length==2){
                        orders.put(s2[0],Integer.parseInt(s2[1]));
                    }
                }
                s=br1.readLine();
            }
//                bw1.write(s);
//                bw1.newLine();
            br1.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        String path2="D:\\java\\Work8\\src\\dishes.txt";
        String filename2="src\\dishes.txt";
        //File file2=new File(path2);
        //获取价格
        int sum=0;
        try{
            br2=new BufferedReader(new InputStreamReader(new FileInputStream(filename2)));
            String ss=br2.readLine();
            while(ss!=null) {
                String[] ss1 = ss.split(":");
                if (ss1.length == 2)
                    sum += orders.get(ss1[0]) * Integer.parseInt(ss1[1]);
                ss=br2.readLine();
            }
            br2.close();
        }catch (Exception e){
            System.out.println("路径错误");
        }

        System.out.println("总价格:"+sum);
    }
}

8-4 成绩文件处理

设计学生类Student,属性:学号(整型);姓名(字符串),选修课程(名称)及课程成绩(整型)。编写一个控制台程序,能够实现Student信息的保存、读取。具体要求:(1)提供Student信息的保存功能:通过控制台输入若干个学生的学号、姓名以及每个学生所修课程的课程名和成绩,将其信息保存到data.dat中;(2)数据读取显示:能够从data.dat文件中读取学生及其课程成绩并显示于控制台。(要求,学号和课程成绩按照整数形式(而非字符串形式)存储)

本题考察使用Object流进行对象序列化(串行化)和反序列化

import java.io.*;
import java.util.*;

public class ScoreFileOperations {
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);
        //提供Student信息的保存功能
        ObjectOutputStream objectOutputStream=null;
        try{
            objectOutputStream=new ObjectOutputStream(
                    new FileOutputStream("data.dat"));
            System.out.println("请输入学生数量");
            int n=sc.nextInt();
            System.out.println("请输入学生信息,例如001 张三 JAVA 95");
            for (int i = 0; i < n ; i++) {
                Studnet studnet=new Studnet(sc.nextInt(),sc.next(),sc.next(),sc.nextInt());
                objectOutputStream.writeObject(studnet);
            }
            objectOutputStream.writeObject(null);//增加一个空对象,用于以后读取时的判断
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                objectOutputStream.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        objectOutputStream.flush();
        objectOutputStream.close();

        //数据读取显示
        try( ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("data.dat")))//这种写法可以省掉finally里的close()语句
        {
            Studnet s=(Studnet)(objectInputStream.readObject());
            while(s!=null){
                System.out.println("学号:"+s.getNo()+" 姓名:"+s.getName()+" 课程"+s.getCourse()+" 成绩"+s.getScore());
                s=(Studnet)objectInputStream.readObject();
            }
        }catch (IOException | ClassNotFoundException e){
            e.printStackTrace();
        }
        objectOutputStream.close();
    }
}

class Studnet implements Serializable{

    private static final long serialVersionUID = 8597440706406158146L;//版本号,标记类的版本,同一版本类下的对象具有兼容性
    //serialVersionUID 的作用是什么呢?
    //JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。
    // 在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。
    // 如果相同说明是一致的,可以进行反序列化
    private int no;
    private String name;
    private String course;
    private int score;

    public Studnet(int no, String name, String course, int score) {
        this.no = no;
        this.name = name;
        this.course = course;
        this.score = score;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

8-5 图书馆持久化 (0分)

构造图书类,包含名称(字符串)、作者(字符串)、出版社(字符串)、版本号(整数)、价格(浮点数),构造图书馆类,其中包含若干图书,用容器存储图书对象,然后定义方法void addBook(Book b)添加图书对象,定义方法void persist(),将所有图书存至本地文件books.dat里,定义方法Book[] restore() 从文件books,dat中读取所有图书,并返回图书列表数组。 main函数中构造图书馆类对象,向其中添加3个图书对象,测试其persist和restore方法。(注意,请使用对象序列化方法实现)

import java.util.*;
import java.io.*;

public class LibraryPersistence {
    public static void main(String[] args) {
        Book b1=new Book("理想国","柏拉图","人民出版社",54156,30);
        Book b2=new Book("疯狂JAVA","李刚","电子工业出版社",564154,59.9f);
        Book b3=new Book("C Primer Plus","Stephen Prata","人民邮电出版社",15415641,89.00f);
        Library library=new Library();
        library.addBooks(b1);
        library.addBooks(b2);
        library.addBooks(b3);
        library.persist();
        library.restore();
    }
}

//构造图书类,包含名称(字符串)、作者(字符串)、出版社(字符串)、版本号(整数)、价格(浮点数)
class Book implements Serializable{

    private static final long serialVersionUID = 4326494201236011493L;
    private String name;
    private String author;
    private String publisher;
    private int version;
    private float price;

    public Book(String name, String author, String publisher, int version, float price) {
        this.name = name;
        this.author = author;
        this.publisher = publisher;
        this.version = version;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    @Override
    public String toString(){
        return "名称:"+getName()+" 作者:"+getAuthor()+" 出版社:"+getPublisher()+" 版本号:"+getVersion()+" 价格:"+getPrice();
    }
}

//构造图书馆类,其中包含若干图书,用容器存储图书对象,然后定义方法void addBook(Book b)添加图书对象,
// 定义方法void persist(),将所有图书存至本地文件books.dat里,
// 定义方法Book[] restore() 从文件books,dat中读取所有图书,并返回图书列表数组

class Library{
    private List<Book> bookList;
    private Book[] bookarray;
    private int size=10;

    public Library(){
        bookList=new ArrayList<>();
        bookarray=new Book[size];
    }

    public void addBooks(Book b){
        bookList.add(b);
    }

    public void persist(){
        ObjectOutputStream oos=null;
        try{
            oos= new ObjectOutputStream(new FileOutputStream("books.dat"));

            Iterator<Book> it=bookList.iterator();
            while (it.hasNext()){
                oos.writeObject(it.next());
            }

            oos.writeObject(null);

            oos.flush();
            oos.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                oos.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public Book[] restore(){
        ObjectInputStream ois=null;
        try{
            ois=new ObjectInputStream(new FileInputStream("books.dat"));
            Book ob=null;
            int i=0;
            while((ob=(Book)ois.readObject())!=null){
                bookarray[i++]=ob;
                if(i==size){//扩容
                    Book []temp=new Book[2*size];
                    System.arraycopy(bookarray,0,temp,0,bookarray.length);
                    bookarray=temp;
                    bookarray[i++]=ob;
                }
            }

            for (int j = 0; j <i ; j++) {
                System.out.println(bookarray[j].toString());
            }
        } catch (FileNotFoundException ex){
            ex.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try{
                ois.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return bookarray;
    }
}

arraycopy
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值