• 第55节:Java当中的IO流-时间api(下)-上


    标题图

    Java当中的IO流(下)-上

    日期和时间

    日期类:java.util.Date
    

    系统时间:

    long time = System.currentTimeMillis();
    
    public class DateDemo {
     public static void main(String[] args){
    
      long time = System.currentTimeMillis();
      System.out.println(time);
    
     }
    }
    

    currentTimeMillis

    public static long currentTimeMillis()
    

    currentTimeMillis是用来返回当前时间的,单位以毫秒,其值的粒度取决于底层操作系统.它是与在1970年1月1日UTC之间的当前时间和午夜之间的差异.

    UTC世界时

    阅读api,类Date

    java.lang.Object
    -> java.util.Date
    

    实现的接口:

    Serializable, Cloneable, Comparable<Data>
    

    从以下版本开始
    JDK1.0

    public class Date extends Object
    implements Serializable, Cloneable, Comparable<Data>
    

    Date有两个附加功能,可以将日期解释为年,月,日,小时,分钟和第二个值,允许格式化和解析日期字符串。但是,从JDK 1.1开始, 要用Calendar类实现在日期和时间字段之间进行转换,并且使用DateFormat类应用于格式化和解析日期字符串, Date中的相应的方法被弃用。

    Calendar
    DateFormat
    

    一天 = 24 * 60 * 60 = 86400

    年,月,日期,小时,分钟,秒值

    年份从整数 y - 1900 表示。
    月份从 0到11 的整数表示。
    0是1月,1是2月,等等;
    日期从 1到31 的整数表示。

    小时由0到23的整数表示。
    分钟由0到59的整数表示。
    一般以0到59的整数表示。
    秒针由0到61的整数表示。

    注意

    Date构造方法:

    Date()
    用来分配Date对象,并且进行初始化对象,时间测量到最近的毫秒
    
    Date(long, date)
    用来分配Date对象,并且进行初始化对象,时间为标准基准时间以后指定毫秒数
    

    使用Date,创建日期对象,封装对象,进行解析毫秒值

    import java.text.DateFormat;
    import java.util.Date;
    
    public class DateDemo {
    	public static void main(String[] args) {
    
    		long time = System.currentTimeMillis();
    		System.out.println(time);
    
    		Date date = new Date(time);
    		System.out.println(date.toString());
    
    	}
    }
    

    toString()为将 Date对象转换为 String的形式
    dow mon dd hh:mm:ss zzz yyyy

    注意

    日期格式化 DateFormat

    DateFormat是日期和时间格式化子类的抽象类,常用SimpleDateFormat,格式化为日期到文本,解析为文本到日期,并且此类提供了很多类方法,(静态方法)

    格式化分很多风格分别为,FULL,LONG,MEDIUM和SHORT.

    java.text
    类 DateFormat
    
    java.lang.Object
    -> java.text.Format
    -> java.text.DateFormat
    
    public abstract class DateFormat extends Format
    

    DateFormat提供了很多类方法,不需要子类,只需要它提供的很多类方法,就可以进行格式化风格,DateFormat为日期格式化对象,可以通过类方法得到日期格式器.

    myString = DateFormat.getDateInstance().format(myDate);
    

    DateFormat.format(Date date)
    DateFormat.getDateInstance().format(myDate);
    风格化:FULL、LONG、MEDIUM(默认风格)和 SHORT

    long time = System.currentTimeMillis();
    Date date = new Date(time);
    
    DateFormat dateFormat = DateFormat.getDateInstance();
    String myString = dateFormat.format(date);
    
    System.out.println(myString);
    

    风格化:

    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);
    
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);
    dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
    

    Class DateFormat

    注意

    Demo案例:

    import java.text.DateFormat;
    import java.util.Date;
    
    public class DateDemo {
    	public static void main(String[] args) {
    
    		long time = System.currentTimeMillis();
    		Date date = new Date(time);
    		System.out.println(date.toString());
    
    		DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);
    		dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
    		String mydate = dateFormat.format(date);
    		System.out.println(mydate);
    	}
    }
    

    IO流

    Input  Output
    

    IO流是用来处理设备之间的数据传输,在Java中数据的传输是通过流的方式进行操作的,在Java中提供了java.io包用于操作流的对象.

    File

    File类是将文件或者文件夹进行封装成对象的,为了方便对文件或者文件夹进行操作.

    什么是递归呢?

    递归就是自己调用自己,就是可以把某功能重复使用.

    输入流为读,输出流为写

    要输入,进行读入
    要输出,进行写出

    流可以分字节流和字符流哦~

    字节流的抽象类:

    InputStream ,OutputStream
    
    子类FileInputStream
    子类FileOutputStream
    

    字符流的抽象列:

    Reader , Writer
    
    子类FileReader
    子类FileWriter
    

    IO流的操作,导入IO包,进行IO异常处理,对流进行关闭

    字符流FileWriter 操作:

    我们要进行创建流对象,就是建立数据存放的文件

    FileWriter fw = new FileWriter("dashu.txt");
    

    然后进行写入的方法,一定要用write()方法,将数据写入:

    fw.write("简书作者: 达叔小生");
    

    最后一定不要忘记,关闭流资源哦~

    fw.close()
    

    这样就可以在文本中写入数据了,字符流创建文件.

    字符流FileReader 操作:

    首先我们要指定文件数据读取的对象,建立一个流对象:

    FileReader fr = new FileReader("dashucoding.txt");
    

    然后创建一个临时存放的数据的数组对象:

    // 因为是字符
    
    char[] ch = new char[1024];
    

    然后进行读取方法,要用到read()方法,将流中的数据进行读取到数组中:

    fr.read(ch);
    

    最后一定不要忘记,关闭流资源哦~

    fr.close()
    

    FileReader 读取:

    FileReader fr = new FileReader("dashucoding.txt");
    
    char[] ch = new char[1024];
    int len = 0;
    while((len=fr.read(ch)) != -1){
     System.out.println(new String(ch,0,len));
    }
    

    高效率-字符流缓冲区的帮助

    有了缓冲区可以对数据的读和写的效率大大提高了.

    BufferedWriter
    BufferedReader
    
    BfferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    

    转换流- InputStreamReader,OutputStreamWriter

    转换流是字符流和字节流之间转换的桥梁,方便了字符流和字节流之间的操作
    转换流的应用场景为当字节流中的数据都是字符时,可以转成字符流进行操作,更加方便快捷.

    字符流体系

    字符流
    
    (Reader, Writer)
    (Reader -> BufferedReader, InputStreamReader)
    (Writer -> BufferedWriter, OutputStreamWriter )
    FileReader, FileWriter
    

    字节流体系

    字节流
    
    (InputStream, OutputStream)
    (InputStream -> FileInputStream, FilterInputStream)
    (OutputStream -> FilterOutputStream, FileOutputStream)
    BufferedInputStream, BufferedOutputStream
    

    抽象类Calendar

    JDK1.1开始,使用Calendar类实现日期和时间字段之间的转换,然后使用DateFormat类来进行格式化和解析日期字符串.

    java.util
    类 Calendar
    
    java.lang.Object
    -> java.util.Calendar
    
    public abstract class Calendar extends Object
    implements Serializable, Cloneable, Comparable<Calendar>
    

    Calendar提供了一些字段:

    YEAR, MONTH, DAY_OF_MONTH, HOUR
    
    Calendar.YEAR
    Calendar.MONTH
    Calendar.DAY_OF_MONTH
    Calendar.HOUR
    

    操作字段:set(),add()和roll(),使用这些方法可以更改日历字段,获取和设置日历字段值,可以调用set()方法,可以使用get,getTimeInMillis,getTime,add和roll进行调用.

    Calendar提供了一个类方法getInstance:

    Calendar rightNow = Calendar.getInstance();
    
    // 获取日历对象
    

    JDK1.1开始就使用这类,不使用Date类了,Calendar 案例:

    import java.util.Calendar;
    
    public class DateDemo {
    	public static void main(String[] args) {
    
    		Calendar c = Calendar.getInstance();
            // System.out.println(c);
            // 获取年
            System.out.println(c.get(Calendar.YEAR));
    	}
    }
    

    搞定年月日

    import java.util.Calendar;
    
    public class DateDemo {
    	public static void main(String[] args) {
    
    		Calendar c = Calendar.getInstance();
    		int year = c.get(Calendar.YEAR);
    		int month = c.get(Calendar.MONTH)+1;
    		int day = c.get(Calendar.DAY_OF_MONTH);
    
            System.out.println(year+"年"+month+"月"+day+"日");
    	}
    }
    

    搞定星期

    import java.util.Calendar;
    
    public class DateDemo {
    	public static void main(String[] args) {
    
    		Calendar c = Calendar.getInstance();
    		int year = c.get(Calendar.YEAR);
    		int month = c.get(Calendar.MONTH)+1;
    		int day = c.get(Calendar.DAY_OF_MONTH);
    		String week = getWeek(c.get(Calendar.DAY_OF_WEEK));
    
    		System.out.println(year+"年"+month+"月"+day+"日"+week);
    	}
    
    	public static String getWeek(int i) {
    		if(i<0 || i>7){
    			throw new RuntimeException(i+"没有对应的星期");
    		}
    		String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    		return weeks[i];
    	}
    }
    

    描述

    文本和日期对象

    // 从time转到date
    Date date = new Date(time)
    
    // 格式化 日期对象转换为日期字符串
    DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
    
    // 文本字符串
    String time = format.format(date);
    // 日期对象转换为日期字符串
    

    文本转换为日期对象,进行解析,即"2018-10-10"转日期对象
    参数是字符串:"2018-10-10"转日期对象
    日期对象 Date date
    凡是字符串转换为其它,都是解析

    public class DateTest {
    	public static void main(String[] args) throws ParseException {
    
    		String mydate = "2018-10-10";
    		DateFormat dateFormat = DateFormat.getDateInstance();
    		Date date = dateFormat.parse(mydate);
    		System.out.println(date);
    	}
    }
    

    这里不同日期风格的文本要对应不同的格式器

    String mydate = "2018-10-10";
    DateFormat dateFormat = DateFormat.getDateInstance();
    
    String mydate = "2018年-10月-10日";
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
    

    如果给出的文本超出提供的风格,那么可以自己定义,进行解析,在Java中知道了这种情况,类DateFormat的子类为SimpleDateFormat对象.

    java.text
    类 SimpleDateFormat
    
    java.lang.Object
    -> java.text.Format
    -> java.text.DateFormat
    -> java.text.SimpleDateFormat
    
    public class SimpleDateFormat extends DateFormat 
    

    文本可能给出"2018/10/10",使用SimpleDateFormat

    public SimpleDateFormat(String pattern)
    参数为:pattern
    是用来描述日期和数据格式的模式
    
    抛出:
    NullPointerException为给定的模式为null
    IllegalArgumentException为给定的模式无效
    

    SimpleDateFormat自己定义相关模式:

    mydate = "2018/10/10 15:14:13";
    
    // 自定义
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
    
    // 解析
    Date date = dateFormat.parse(mydate);
    
    System.out.println(date);
    

    Class SimpleDateFormat

    SimpleDateFormat是一个具体的类,可以格式化,日期转文本,也可以解析,文本转日期和归一化.

    描述

    描述

    练习获取天数

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.util.Date;
    
    public class DateDemo {
    	public static void main(String[] args) throws ParseException {
    
    		/*
    		 * 思路:
    		 * 1,从2018-10-2到2018年10月8日有多少天?相减
    		 * 2,字符串不能相减,毫秒值可以相减。
    		 * 3,获取毫秒值  毫秒值 -> 日期对象, 日期对象 -> 毫秒值。
    		 * 4,获取日期对象  需要将 字符串文本 -> 解析 -> 日期对象。
    		 */
    
    		// 两者相差多少天,给定日期模式
    		String date1 = "2018-10-2";
    		String date2 = "2018年10月8日";
    
            // 进行模式解析
    		int style_1 = DateFormat.MEDIUM;
    		int style_2 = DateFormat.LONG;
    
    		// 定义方法, 获取天数 参数文本日期, 模式
    		int days = getDays(date1,date2,	style_1,style_2);
    
            // 获取天数
    		System.out.println("days="+days);
    
    	}
    
    	private static int getDays(String date1, String date2,
    			int style_1, int style_2) throws ParseException {
    
    	    // 进行模式
    		DateFormat format_1 = DateFormat.getDateInstance(style_1);
    		DateFormat format_2 = DateFormat.getDateInstance(style_2);
    
            // 进行模式解析, 日期对象 解析 -> 日期对象。
    		Date date_1 = format_1.parse(date1);
    		Date date_2 = format_2.parse(date2);
    
            // 获取毫秒数 日期对象 -> 毫秒值。
    		long time_1 = date_1.getTime();
    		long time_2 = date_2.getTime();
    
    		long time = Math.abs(time_1 - time_2);
    		int day = (int)(time/1000/60/60/24);
    
    		return day;
    	}
    }
    

    解决2月份的天数问题?

    使用方法:

    add(int field, int amount)
    返回为abstract void 
    
    为给定的日历字符安添加或者减去指定的时间量
    
    import java.util.Calendar;
    
    public class DateTest {
    	public static void main(String[] args) {
    			show(year);
    	}
    
    	public static void show(int year) {
    		Calendar c = Calendar.getInstance();
    
            // 2+1 = 3;
    		c.set(year, 2, 1);
    		// 知道3月1日的前一天就是2月的最后一天,就知道2月份的天数。
    		c.add(Calendar.DAY_OF_MONTH, -1);
    
    		int year1 = c.get(Calendar.YEAR);
    		int month = c.get(Calendar.MONTH) + 1;
    		int day = c.get(Calendar.DAY_OF_MONTH);
    		String week = getWeek(c.get(Calendar.DAY_OF_WEEK));
    
    		System.out.println(year1 + "年" + month + "月" + day + "日  " + week);
            System.out.println(day+"天");
    	}
    
    	public static String getWeek(int i) {
    		if (i < 0 || i > 7) {
    			throw new RuntimeException(i + "没有对应的星期");
    		}
    
    		String[] weeks = { "", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
    		return weeks[i];
    	}
    }
    

    打印流,基本类型数据流,流对象,RandomAccessFile

    IO包中的打印流

    PrintWriter与PrintStream可以用来操作输入流和文件
    

    操作基本数据类型

    DataInputStream与DataOutputStream
    // 操作字节数组
    
    ByteArrayInputStream与ByteArrayOutputStream
    // 操作字符数据
    
    CharArrayReader与CharArrayWriter
    // 操作字符串
    
    StringReader 与 StringWriter
    

    操作对象

    ObjectInputStream与ObjectOutputStream
    

    RandomAccessFile

    随机访问文件,自身具备读写的方法。

    打印流

    PrintStream 和 PrintWriter

    FileOutputStream fos = new FileOutputStream("dashu.txt");
    fos.write(Integer.toString(108).getBytes();
    fos.close();
    
    java.io
    类 FilterOutputStream
    
    java.lang.Object
    -> java.io.OutputStream
    -> java.io.FilterOutputStream
    
    public class FilterOutputStream extends OutputStream
    
    已知子类:
    BufferedOutputStream
    PrintStream
    

    PrintStream

    java.io
    类 PrintStream
    
    java.lang.Object
    -> java.io.OutputStream
    -> java.io.FilterOutputStream
    -> java.io.PrintStream
    
    public class PrintStream extends FilterOutputStream
    implements Appendable, Closeable
    
    方法 说明
    PrintStream(File file) 用于创建指定文件且不带自动刷新的新打印流
    PrintStream(File file, String csn) 用于创建指定文件名称和字符集且不带自动行刷新的新打印流
    PrintStream(OutputStream out) 用于创建新的打印流
    PrintStream(OutputStream out, boolean autoFlush) 用于创建新的打印流
    PrintStream(OutputStream out, boolean autoFlush, String encoding) 用于创建新的打印流
    PrintStream(String fileName) 用于创建指定文件名称且不带自动行刷新的新打印流
    PrintStream(String fileName, String csn) 用于创建指定文件名称和字符集且不带自动行刷新的新打印流

    文件字节输出流

    FilterOutputStream,写东西到文件

    FileOutputStream fos = new FileOutputStream("dashu.txt");
    fos.write(Integer.toString(108).getBytes();
    fos.close();
    
    // 进行比较可以用PrintStream
    
    FileOutputStream fos = new FileOutputStream("dashu.txt");
    
    // 添加额外功能PrintStream
    PrintStream ps = new PrintStream(fos);
    
    // 如果用
    // ps.write(97);
    // 那么就会在 dashu.txt 该文件中显示一字节 为 a
    // 使用 print() 方法
    
    ps.print(97);
    // 在 dashu.txt 文件中显示 为 97
    
    ps.close();
    

    点击源码 print() 方法:

    public void print(int i){
     write(String.valueOf(i));
    }
    

    还可以升级 PrintStream :

    PrintStream ps = new PrintStream("dashu.txt");
    ps.print(97);
    ps.close();
    

    Class PrintStream

    从以下版本开始:
    JDK1.0

    描述

    PrintWriter

    键盘录入

    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    

    从以下版本开始:
    JDK1.1

    java.lang Object
    -> java.io.Writer
    -> java.io.PrintWriter
    
    public class PrintWriter extends Writer
    

    描述

    描述

    PrintWriterDemo 案例:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    
    public class PrintWriterDemo {
    	public static void main(String[] args) throws IOException {
    
    		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    		PrintWriter out = new PrintWriter(System.out,true);
    		
    		String line = null;
    		while((line=bufr.readLine())!=null){
    			if("over".equals(line)){
    				break;
    			}
    			out.println(line.toUpperCase());
    		}
    		out.close();
    	}
    }
    

    基本类型数据流

    DataOutputStream
    DataInputStream
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class DataStreamDemo {
    	public static void main(String[] args) throws IOException {
    		readData();
    	}
    
    	public static void readData() throws IOException {
    		FileInputStream fis = new FileInputStream("dashu.txt");
    		DataInputStream dis = new DataInputStream(fis);
    		
    		int num = dis.readInt();
    		System.out.println("num="+num);
    		dis.close();
    		
    	}
    
    	public static void writeData() throws IOException {
    		FileOutputStream fos = new FileOutputStream("dashucoding.txt");
    		DataOutputStream dos = new DataOutputStream(fos);
    		dos.writeInt(97);
    		dos.close();
    	}
    }
    

    描述

    描述

    操作数组和字符串的流对象

    专门操作字节数组的流对象为 ByteArrayOutputStream

    java.lang.Object
    -> java.io.OutputStream
    -> java..io.ByteArrayOutputStream
    
    public class ByteArrayOutputStream
    extends OutputStream
    

    ByteArrayOutputStream 把数组直接封装起来,并提供流的读写方法来操作数组,此类实现了一个输出流,数据被写入到一个byte数组,获取数据的方法为 toByteArray()toString(). 其缓冲区会随着数据的增长而增加.
    关闭 ByteArrayOutputStream 没有任何效果,所以不用关闭.

    ByteArrayStreamDemo 案例:

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    
    public class ByteArrayStreamDemo {
    	public static void main(String[] args) {
    		// 源
    		ByteArrayInputStream bis = new ByteArrayInputStream("dashucoding".getBytes());
    		
    		// byte[] buff = "dashucoding".getBytes();
    		// for(byte b : buff){
    		// 	bos.write(b);
    		// }
    		
    		// 目的
    		ByteArrayOutputStream bos = new ByteArrayOutputStream();
    		
    		int ch = 0;
    		while((ch=bis.read())!=-1){
    			bos.write(ch);
    		}
    		// 因为不用调用底层资源,所以不用关闭, 不会抛出IOException.
    		System.out.println(bos.toString());
    	}
    }
    

    描述

    描述

    IO流中的 RandomAccessFile

    需求分析: 要对文件进行 读 或者 写 的操作

    java.io
    类 RandomAccessFile
    
    java.lang.Object
    -> java.io.RandomAccessFile
    
    public class RandomAccessFile extends Object
    implements DataOutput, DataInput, Closeable
    

    RandomAccessFile 对文件进行随机访问, 进行 读 和 写.(随机访问,操作文件,封装了读取和写入的流, 字节输入流和字节输出流, 提供了文件指针)

    描述

    IO包中工具类对象 RandomAccessFile 案例:

    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    public class RandomAccessFileDemo {
    	public static void main(String[] args) throws IOException {
    
    		 // 内部是用byte数组进行存储数据
    		 // 提供了一个对数组操作的文件指针
    		 // 通过 getFilePointer 方法读取,并通过 seek 方法设置
    	   	 //  writeFile();
    		readFile();
    	}
    
    	public static void readFile() throws IOException {
    	    // r 为都
    		RandomAccessFile raf = new RandomAccessFile("dashu.txt", "r");
    		// 改变指针的位置,想读谁就读谁
    		raf.seek(8*3);
    		
    		byte[] buff = new byte[4];
    		raf.read(buff);
    		String name = new String(buff);
    		System.out.println("name="+name);
    		
    		int age = raf.readInt();
    		System.out.println("age="+age);
    		
    		raf.close();
    	}
    
    	public static void writeFile() throws IOException {
    		// rw 为进行读写操作
    		RandomAccessFile raf = new RandomAccessFile("dashu.txt", "rw");
    		
    		// 存储 姓名 和 年龄。
    		// raf.write("张三".getBytes());
    		// raf.writeInt(27);
    		// raf.write("李四".getBytes());
    		// raf.writeInt(38);
    		// 通过seek()方法进行在哪里写入
    		raf.seek(4);
    		
    		raf.write("简书作者: 达叔小生".getBytes());
    		raf.writeInt(12);
    
    		// 文件指针可以通过读取getFilePointer方法和由设置seek方法
    		System.out.println(raf.getFilePointer());
    		raf.close();
    	}
    }
    

    RandomAccessFile 中是通过数组进行存储的,RandomAccessFile 不会进行覆盖,如果之前保留了数据,然后会在文件中继续保留,当导入的数据与之前的数据都在同一位置,则数据会进行覆盖.

    往后余生,唯独有你
    简书作者:达叔小生
    90后帅气小伙,良好的开发习惯;独立思考的能力;主动并且善于沟通
    简书博客: https://www.jianshu.com/u/c785ece603d1

    结语

    • 下面我将继续对 其他知识 深入讲解 ,有兴趣可以继续关注
    • 小礼物走一走 or 点赞
  • 相关阅读:
    集合---Map
    一个机器部署多个tomcat
    JavaScript要不要加分号";"
    Nodejs 路径 /, ./, ../, ..// 的区别
    玩转Vue的24个小程序---基础篇
    如何创建Node.js Web服务器
    为什么Ajax XMLHttpRequest POST方法传递参数失败了
    字典元素如何遍历
    Beautiful Soup 如何获取到href
    如何查看Ajax请求
  • 原文地址:https://www.cnblogs.com/dashucoding/p/9767326.html
Copyright © 2020-2023  润新知