Java-IO流

IO流

什么是流

​ 流(IO),在计算机系统中,将不同的输入输出源统一抽象为流,流是一种实现数据交换技术的核心,比较常见的流的使用在于:文件操作,网络数据传输等;流由两大核心部分构成:1.Input(输入),2.Output(输出);通俗的理解为人的嘴(输出)和耳朵(输入),对流的使用就分为两种操作:读和写;java中所有有关流的类都来自于java.io包。

流的分类

java-IO将流分为几种类别:

  1. 按流向分为:输入和输出
  2. 按类型分为:字节和字符
  3. 按功能分为:节点流和处理流

字节流

所谓字节流,其实就是将数据以字节为单位进行读写相关操作,字节流一般用于对于一些二进制文件(图片,音频,视频等)进行读写操作,java中的字节流都是来自以下两个抽象类:

  1. InputStream(字节输入流)
  2. OutputStream(字节输出流)

InputStream类

inputStream类是所有字节输入流的父类,是一个抽象类,常用方法包含以下:

  1. available():获取当前流中的可读字节数
  2. close():关闭此流
  3. read():从流中读取一个字节,返回读取到的字节
  4. read(byte[] b):将流中读取到的字节存入到指定的字节数组中,返回真实读取的长度,读取不到返回-1
  5. read(byte[] b,int offset,int len):将流中读取奥的字节存入到指定的字节数组中(跳过offset个字节存储,存储长度为len),读取不到返回-1

OutputStream类

OutputStream类是所有字节输出流的父类,是一个抽象类,常用方法如下:

  1. write(byte[] b):将字节数组中的内容写入输出源(文件,网络,内存)
  2. write(byte[] b,int offset,int len):将字节数组中的内容从offset开始写入len长到输出源
  3. write(int b):将一个字节写入输出源
  4. flush():将流中的数据强制刷新到输出源
  5. close():关闭此流

字符流

​ 字符流,顾名思义,是以字符的形式对输入输出源操作,通常情况下一个字符表示两个字节,但是在一些unicode编码,如UTF-8则使用3个字节表示,但是由于字符流的特殊性,一般用字符流主要操作一些文本输入输出源(文本文档,记事本文件等字符数据);java中所有的字符流都从以下两个抽象类继承:

  1. Reader 字符输入流
  2. Writer 字符输出流

Reader

字符输入流,是所有字符输入流的父类,是一个抽象类,内部的常见方法如下:

  1. read():读取并返回一个字符
  2. read(char[] c):将从流中读取的字符存储到字符数组
  3. read(char[] c,int offset,int len):将从流中读取的字符存入字符数组(跳过offset个字节,写入len长)
  4. ready():返回此流是否准备好被读取的状态
  5. close():关闭此流

Writer

字符输出流,是所有字符输出流的父类,是一个抽象类,内部的常见方法如下:

  1. append(char c):向流中追加一个字符
  2. append(CharSequence c):向流中追加一个字符序列(字符串)
  3. witer(String s):写入一个字符串到目标输出源
  4. witer(char[] c):写入字符数组到目标输出源

转换流、缓冲流打印流

​ 由于以上所提到的流,按照功能来说都属于节点流(直接跟输入输出源打交道),而在实际开发中有些需求可能会涉及到需要将字节流转换为字符流,或者将字符流转换为字节流等一些转换操作;另外也有可能需要将这些低级的节点流提高读取和写入效率,因此还需要一些高级流来进行处理,因此这些高级流也被称之为处理流,比如:转换流,缓冲流,打印流等。

转换流

java-io中的转换流主要分为两个:

  1. InputStreamReader:将字节流转换为字符流的桥梁
  2. OutputStreamWriter:将字符流转换为字节流的桥梁

缓冲流

缓冲流的出现主要为了提高节点流的读取和写入效率,使用方式通常为将其他节点流包装起来,io包中的缓冲流分为以下几个:

  1. BufferedReader
  2. BufferedWriter
  3. BufferedInputStream
  4. BufferedOutputStream

打印流

另外在IO包中还提供了两个特殊的流,这两个流只有输出,没有输入:

  1. PrintStream 字节打印流
  2. PrintWriter 字符打印流

实现目录拷贝

FileCopyUtils.java

/**
 * 文件拷贝工具
 * @author 耕作的牛
 */
public class FileCopyUtils {

	/**
	 * 将一个源file对象拷贝到另一个目标file
	 * @param source  源文件(可能是目录)
	 * @param target  目标目录
	 * @throws IOException 
	 */
	public static void copy(File source,File targetDir) throws IOException{
		//判断当前需要被拷贝对象是目录还是标准文件
		if(source.isDirectory()){
			//在目录中创建子目录(不存在)
			targetDir = new File(targetDir,source.getName());
			if(!targetDir.exists()){
				//如果目录不存在则试图创建
				if(!targetDir.mkdirs()){
					throw new FileNotFoundException("目录创建失败,请检查权限");
				}
			}
			//读取目录
			File[] files = source.listFiles();
			if(Objects.nonNull(files)){				
				for (int i = 0; i < files.length; i++) {
					copy(files[i],targetDir);
				}
			}
		}else{
			//文件拷贝
			copyFile(source,targetDir);
		}
		
	}

	private static void copyFile(File source, File targetDir) throws IOException {
		BufferedInputStream bis = null;
		BufferedOutputStream bow = null;
		try{
			//获取源文件的输入流并包装为缓冲流
			bis = new BufferedInputStream(new FileInputStream(source));
			//根据源文件文件名组合目标目录成为新文件对象
			File target = new File(targetDir,source.getName());
			//获取目标文件的输出流
			bow = new BufferedOutputStream(new FileOutputStream(target));
			//声明字节缓冲区,缓存读取的字节数据
			byte[] b = new byte[1024];
			int len = 0;
			//循环读写
			while((len = bis.read(b)) != -1){
				bow.write(b, 0, len);
			}
		}finally{			
			//关闭资源
			if(bow != null)bow.close();
			if(bis != null)bis.close();
		}
	}
}

测试类:

public class TestCopy {
	public static void main(String[] args) throws IOException {	
		//源file
		File f1 = new File("D:/javacode"); 
		//目标file
		File f2 = new File("C:/Users/Desktop"); 
		//拷贝
		FileCopyUtils.copy(f1, f2);
	}
}

实现交易记录系统

交易记录实体类:TransRecord.java

/**
 * 交易记录类
 * @author 耕作的牛
 */
public class TransRecord {

	/**客户号*/
	private String num;
	/**姓名*/
	private String name;
	/**机构号*/
	private String jnum;
	/**性别*/
	private String sex;
	/**账号*/
	private String account;
	/**发生时间*/
	private Date time;
	/**发生金额*/
	private BigDecimal cash;
	
	public TransRecord() {
		// TODO Auto-generated constructor stub
	}
	
	public TransRecord(String num, String name, String jnum, String sex, String account, Date time, BigDecimal cash) {
		super();
		this.num = num;
		this.name = name;
		this.jnum = jnum;
		this.sex = sex;
		this.account = account;
		this.time = time;
		this.cash = cash;
	}


	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getJnum() {
		return jnum;
	}
	public void setJnum(String jnum) {
		this.jnum = jnum;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAccount() {
		return account;
	}
	public void setAccount(String account) {
		this.account = account;
	}
	public Date getTime() {
		return time;
	}
	public void setTime(Date time) {
		this.time = time;
	}
	public BigDecimal getCash() {
		return cash;
	}
	public void setCash(BigDecimal cash) {
		this.cash = cash;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((account == null) ? 0 : account.hashCode());
		result = prime * result + ((cash == null) ? 0 : cash.hashCode());
		result = prime * result + ((jnum == null) ? 0 : jnum.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((num == null) ? 0 : num.hashCode());
		result = prime * result + ((sex == null) ? 0 : sex.hashCode());
		result = prime * result + ((time == null) ? 0 : time.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		TransRecord other = (TransRecord) obj;
		if (account == null) {
			if (other.account != null)
				return false;
		} else if (!account.equals(other.account))
			return false;
		if (cash == null) {
			if (other.cash != null)
				return false;
		} else if (!cash.equals(other.cash))
			return false;
		if (jnum == null) {
			if (other.jnum != null)
				return false;
		} else if (!jnum.equals(other.jnum))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (num == null) {
			if (other.num != null)
				return false;
		} else if (!num.equals(other.num))
			return false;
		if (sex == null) {
			if (other.sex != null)
				return false;
		} else if (!sex.equals(other.sex))
			return false;
		if (time == null) {
			if (other.time != null)
				return false;
		} else if (!time.equals(other.time))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "TransRecord [num=" + num + ", name=" + name + ", jnum=" + jnum + ", sex=" + sex + ", account=" + account
				+ ", time=" + time + ", cash=" + cash + "]";
	}

}

交易记录管理类:TransRecordManager.java

/**
 * 1.面向对象(封装,多态)
 * 2.常用类(Date,BigDecimal,DateFormat,SimpleDateFormat,String,File,Objects,Collections)
 * 3.异常处理
 * 4.新特性(lambda表达式,流式API)
 * 5.IO流
 * 
 * 交易记录管理类
 * @author 耕作的牛
 *
 */
public class TransRecordManager{
   
	//声明成员变量用于存储所有的交易记录数据
	private List<TransRecord> records = new ArrayList<>();
	
    /**
    * 加载数据
    * @param in - 数据流
    * @return
    * @throws - 解析过程中IO错误
    */
    public void load(InputStream in) throws IOException{
    	//将获取的字节流转换为字符流并包装成缓冲流
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = "";
        while((line = br.readLine()) != null){
        	//排除注释行(以“#”开头)
        	if(!line.startsWith("#")){
        		TransRecord record = parseDataToObj(line);
        		records.add(record);
        	}
        }
    }
    
    /**
     * 将一行文本数据解析为一个交易记录对象
     * @param line
     * @return
     */
    private TransRecord parseDataToObj(String line) {
		TransRecord tr = new TransRecord();
    	String[] data = line.split("\\|");
		tr.setNum(data[0]);
    	tr.setName(data[1]);
    	tr.setJnum(data[2]);
    	tr.setSex(Objects.equals(data[3],"1") ? "男" : "女");
    	tr.setAccount(data[4]);
    	tr.setCash(new BigDecimal(data[6]));
    	try {
			DateFormat fmt =new SimpleDateFormat("yyyyMMddHHmmss"); 
			Date time = fmt.parse(data[5]);
			tr.setTime(time);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return tr;
	}

	/**
    * 加载数据
    * @param fileName - 包含记录数据的文件名
    * @return
    * @throws - 解析过程中IO错误
    */
    public void load(String fileName) throws IOException{
    	File f = new File(fileName);
    	InputStream is = new FileInputStream(f);
    	load(is); 
    }

    /**
    * 取所有记录
    * @return 所有记录数组或null
    */
    public List<TransRecord> getAll(){
        return records;
    }

    /**
    * 按客户号查询记录
    * @param customerNumber - 客户号
    * @return 符合条件的记录数组或null
    */
    public List<TransRecord> findByCustomerNumber(String customerNumber){
        return records.stream()
        			  .filter(r->Objects.equals(r.getNum(), customerNumber))
        			  .collect(Collectors.toList());
    }

    /**
    * 按日期段查询记录
    * @param start - 开始日期
    * @param end - 结束日期
    * @return 符合条件的记录数组或null
    */
    public List<TransRecord> findByDate(String start, String end){
    	try {
			DateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
			long from = fmt.parse(start).getTime();
			long to = fmt.parse(end).getTime();
			
//			List<TransRecord> list = new ArrayList<>();
//			for(TransRecord tr : records){
//				long now = tr.getTime().getTime();
//				if(now >= from && now <= to){
//					list.add(tr);
//				}
//			}
//			return list;
			
			return records.stream()
					      .filter(r->{
					    	  long now = r.getTime().getTime();
					    	  return now>=from && now <=to;
					      })
					      .collect(Collectors.toList());
			
		} catch (ParseException e) {
			e.printStackTrace();
		}    	
        return null;
    }

    /**
    * 取得总金额
    * @return 总金额
    */
    public BigDecimal totalAmount(){
    	BigDecimal result = new BigDecimal(0); 
    	for (TransRecord tr : records) {
			BigDecimal cash = tr.getCash();
			result = result.add(cash);
		}
        return result;
    }

    /**
    * 按金额排序
    * @return 按金额升序排序的结果
    */
    public List<TransRecord> sortByAmount(){
    	Collections.sort(records, (r1,r2)->r1.getCash().compareTo(r2.getCash()));
        return records;
    }

    /**
    * 打印  
    * @param out - 输出流
    */
    public void print(OutputStream out){
        
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值