标题图
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 后帅气小伙, 良好的开发习惯; 独立思考的能力; 主动并且善于沟通
来源: http://www.jianshu.com/p/887ee6fcb44b