第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流
InputOutput
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後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: ofollow,noindex">https://www.jianshu.com/u/c785ece603d1
結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊