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 点赞