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 點贊