Day14-Java
文章目錄
- Day14-Java
- 1、定時器
- 2、UUID類
- 3、Base64加密處理
- 4、ThreadLocal類
- 5、IO—File類
- 5.1 基本操作
- 5.2 取得檔案資訊
- 5.3 綜合案例:目錄串列
- 6、IO— 位元組流與字符流
- 6.1 位元組輸出流:OutputStream
- 6.2 位元組輸入流:InputStream
- 6.3 字符輸出流:Writer
- 6.4 字符輸入流:Reader
- 6.5 位元組流與字符流區別
- 7、轉換流
1、定時器
推動整個計算機硬體的發展的核心關鍵性技術就是時鐘,所以在企業開發中定時操作往往成為開發重點,而在JDK本身也支持這種定時調度的處理操作,這種操作不會直接使用,還是和多執行緒有關,
如果想要定時調度處理操作,需要兩個類
- 定時調度任務:java.util.TimerTask
- 定時調度操作:java.util.Timer
package com.day14.demo;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class MyTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS").format(new Date()));
}
}
public class TaskDemo {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new MyTask(), 1000,2000);
}
}
2、UUID類
UUID類是根據你當前的地址還有時間戳自動生成一個幾乎不會重復的字串,
package com.day14.demo;
import java.util.UUID;
public class UUIDDemo {
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
}
以后再檔案上傳等類似的操作中通過UUID類來進行簡單的檔案名稱,以防止重名的問題,
3、Base64加密處理
Base64是一種資料加密演算法,使用整個演算法可以使我們的資料進行安全處理,如果要想進行加密處理可以使用兩個:加密器、解密器,
加密處理
package com.day14.demo;
import java.util.Base64;
public class Base64Demo {
public static void main(String[] args) {
String msg = "123456";
String emsg = Base64.getEncoder().encodeToString(msg.getBytes());
System.out.println("加密:" + emsg);
byte[] decode = Base64.getDecoder().decode(emsg);
System.out.println("解密:" + new String(decode));
}
}
多次加密
package com.day14.demo;
import java.util.Base64;
public class Base64Demo {
public static void main(String[] args) {
String msg = encode("123456");
String emsg = encode(encode(encode(msg)));
System.out.println("加密:" + emsg);
byte[] decode = Base64.getDecoder().decode(emsg);
System.out.println("解密:" + new String(decode));
}
public static String encode(String code){
return Base64.getEncoder().encodeToString(code.getBytes());
}
}
還有一個做法就是種子樹
package com.day14.demo;
import java.util.Base64;
public class Base64Demo {
public static void main(String[] args) {
String sed = encode("zsr--rsz");
String msg = "123456"+sed;
String emsg = encode(msg);
System.out.println("加密:" + emsg);
byte[] decode = Base64.getDecoder().decode(emsg);
System.out.println("解密:" + new String(decode));
}
public static String encode(String code){
return Base64.getEncoder().encodeToString(code.getBytes());
}
}
必須保證長度,以后的開發將Base64和MD5一起開發,長度是32位,
4、ThreadLocal類
TheadLocal類不繼承Thread類,也不實作Runable介面,ThreadLocal類為每一個執行緒都維護了自己獨有的變數拷貝,每個執行緒都擁有自己獨立的變數,
ThreadLocal采用了“以空間換時間”的方式:訪問并行化,物件獨享化,前者僅提供一份變數,讓不同的執行緒排隊訪問,而后者為每一個執行緒都提供了一份變數,因此可以同時訪問而互不影響,
ThreadLocal的實作是這樣的:每個Thread維護了一個ThreadLocalMap映射表,這個映射表的key是ThreadLocal實體本身,Value是真正需要存盤的變數,也就是說,ThreadLocal本身并不存盤值,它只是作為一個key來讓執行緒從ThreadLocalMap獲取value,注意,ThreadLocalMap是使用ThreadLocal的弱參考作為key的,弱參考的物件在GC時會被回收,
通過給方法傳遞引數,呼叫兩個執行緒輸出不同的資訊
package com.day14.demo;
class Message{
private String note;
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
};
}
class GetMessage{
public void print(Message msg){
System.out.println(Thread.currentThread().getName() + msg.getNote());
}
}
public class ThreadLocalDemo {
public static void main(String[] args) {
new Thread(()->{
Message message = new Message();
message.setNote("Hello,world!!");
new GetMessage().print(message);
},"用戶A").start();
new Thread(()->{
Message message = new Message();
message.setNote("Hello,world!!zsr");
new GetMessage().print(message);
},"用戶B").start();
}
}
但是我現在的需求是不希望通過傳遞傳輸給GetMessage的print方法,還希望實作相同的功能,
package com.day14.demo;
class Message{
private String note;
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
};
}
class GetMessage{
public void print(){
System.out.println(Thread.currentThread().getName() + MyUtil.message.getNote());
}
}
class MyUtil{
public static Message message;
}
public class ThreadLocalDemo {
public static void main(String[] args) {
new Thread(()->{
Message msg = new Message();
msg.setNote("Hello,world!!");
MyUtil.message = msg;
new GetMessage().print();
},"用戶A").start();
new Thread(()->{
Message msg = new Message();
msg.setNote("Hello,world!!zsr");
MyUtil.message = msg;
new GetMessage().print();
},"用戶B").start();
}
}
我們發現兩個執行緒的內容并沒有同步輸出,所以我們會想到通過ThreadLocal類來解決此資料不同步的問題,

public class ThreadLocal<T> extends Object
這個類里面有幾個重要的方法:
- 取得資料:public T get()
- 存放資料:public void set(T value)
- 洗掉資料:public void remove()
利用ThreadLocal來解決當前我問題
package com.day14.demo;
class Message{
private String note;
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
};
}
class GetMessage{
public void print(){
System.out.println(Thread.currentThread().getName() + MyUtil.get().getNote());
}
}
class MyUtil{
private static ThreadLocal<Message> tl = new ThreadLocal<Message>();
public static void set(Message msg){
tl.set(msg);
}
public static Message get(){
return tl.get();
}
}
public class ThreadLocalDemo {
public static void main(String[] args) {
new Thread(()->{
Message msg = new Message();
msg.setNote("Hello,world!!");
MyUtil.set(msg);
new GetMessage().print();
},"用戶A").start();
new Thread(()->{
Message msg = new Message();
msg.setNote("Hello,world!!zsr");
MyUtil.set(msg);
new GetMessage().print();
},"用戶B").start();
}
}
這樣我們就解決了資料不同步的問題了,
5、IO—File類
5.1 基本操作
如果要想學好IO,必須要清楚抽象類、IO的操作部分掌握兩個代碼模型,IO的核心組成五個類(File、OutputStream、InputStream、Writer、Reader)一個介面(Serializable),
再java.io是一個與文本本身操作有關的程式(創建、洗掉、資訊取得—)
如果要想使用File類操作檔案的話,那么肯定要通過構造方法實體化File類物件,而實體化File類物件的程序之中主要使用以下兩種構造方法:
- 方法一:public File(String pathname);
- 方法二:public File(File parent,String child).
檔案的基本操作,主要有以下幾種功能:
-
**創建一個新檔案:**public boolean createNewFile() throws IOException
-
**洗掉檔案:**public Boolean delete();
-
**判斷路徑是否存在:**public Boolean exists();
創建新檔案
package com.day14.demo;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("f:\\hello.txt");
file.createNewFile();
}
}
如果檔案存在進行洗掉,不存在進行創建
package com.day14.demo;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
File file = new File("f:\\hello.txt");
if(file.exists()){//檔案存在
file.delete();
}else{//檔案不存在
file.createNewFile();//創建檔案
}
}
}
本程式操作就表示如果檔案存在則洗掉,如果不存在則創建一個新的檔案,此時基本功能是實作了,不過這個程式此時存在三個問題:
問題一:關于路徑的分隔符
在windows操作之中,使用“\”作為路徑分隔符,而在Linux系統下使用“/”作為路徑分隔符,而實際的開發而言,大部分情況下會在windows中做開發,而后將專案部署在Linus,那么此時,路徑的分隔符都需要進行修改,這樣實在是國語麻煩,為此在File類之中提供了一個常量:public static final String separator(按照Java的命名規范來講,對于全域常量應該使用大寫字母的方式定義,而此處使用的是小寫,是由Java的發展歷史所帶來的問題),
//由不同的作業系統的JVM來決定最終的separator是什么內容File file = new File("f:" + File.separator + "hello.txt");
問題二:是有可能會出現的延遲問題
發現程式執行完成之后,對于檔案的創建或者是洗掉是會存在一些操作上的延遲,如果現在假設先洗掉了一個檔案,而后立刻判斷此檔案是否存在,那么可能得到的結果就是錯誤的(為true),一位所有的*.class檔案都要通過JVM與作業系統間接操作,這樣就有可能會出現延遲的問題,

問題三:目錄問題
之前進行檔案創建的時候都是在根目錄下創建完成的,如果說現在要創建的檔案有目錄呢?例如,現在要創建一個f:\hello\hello.txt檔案,而此時在執行程式的時候hello目錄不存在,這個時候執行的話就會出現錯誤提示:
Exception in thread "main" java.io.IOException: 系統找不到指定的路徑,
因為現在目錄不存在,所以不能創建,那么這個時候必須首先判斷要創建檔案的父路徑是否存在,如果不存在應該創建一個目錄,之后再進行檔案的創建,而要想完成這樣的操作,需要一下幾個方法支持:
**找到一個指定檔案的父路徑:**public File getParentFile();
**創建目錄:**public boolean mldirs(),
package com.day14.demo;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
//由不同的作業系統的JVM來決定最終的separator是什么內容
File file = new File("f:" + File.separator +"hello" + File.separator + "hello.txt");
if(!file.getParentFile().exists()){//父目錄
file.getParentFile().mkdirs();//創建父目錄
}
if(file.exists()){//檔案存在
file.delete();
}else{//檔案不存在
file.createNewFile();//創建檔案
}
}
}
以后在任何的java.io.File類開發程序之中,都一定要考慮檔案目錄的問題,
5.2 取得檔案資訊
在File類之中還可以通過以下的方法取得一些檔案的基本資訊:
| 方法名稱 | 描述 |
|---|---|
| public String getName() | 取得檔案的名稱 |
| public boolean isDirectory() | 給定的路徑是否為檔案夾 |
| public boolean isFile() | 給定的路徑是否是檔案 |
| public boolean isHidden() | 是否是隱藏檔案 |
| public long lastModified() | 檔案的最后一次修改日期 |
| public long length() | 取得檔案大小,是以位元組為單位回傳的, |
獲取檔案的大小資訊以及核心資訊
package com.day14.demo;import java.io.File;import java.math.BigDecimal;import java.text.SimpleDateFormat;import java.util.Date;class MyMath{ public static double round(double num, int scale){ return Math.round(num * Math.pow(10, scale)) / Math.pow(10, scale); }}public class FileDemo2 { public static void main(String[] args) { File file = new File("f:" + File.separator + "701_03_支付寶沙箱使用.avi"); if(file.exists() && file.isFile()){ System.out.println("1檔案大小為:" + MyMath.round(file.length() / (double) 1024 / 1024, 2)); System.out.println("最后一次修改日期:"+ new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date(file.lastModified()))); System.out.println("2檔案大小為:" + new BigDecimal(file.length() / (double)1024 /1024).divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP).doubleValue()); } }}
**列出目錄內容:**public File [] listFiles(),此方法將目錄中的所有檔案以File物件陣列的方式回傳;
列出目錄的所有結構
package com.day14.demo;
import java.io.File;
import java.util.Arrays;
public class FileDemo3 {
public static void main(String[] args) {
File file = new File("f:" + File.separator);
if(file.exists() && file.isDirectory()){
File[] listFiles = file.listFiles();
System.out.println(Arrays.toString(listFiles));
}
}
}
5.3 綜合案例:目錄串列
現在希望把一個目錄下的全部檔案都列出來,那么這種情況下只能采用遞回:因為列出一個目錄下的全部檔案或著檔案夾之后,如果發現列出的內容是檔案夾,則應該向后繼續列出,
列出指定目錄下的所有檔案
package com.day14.demo;
import java.io.File;
public class FileListDemo {
public static void main(String[] args) {
File file = new File("f:" + File.separator);
list(file);
}
public static void list(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
if(files != null){
for (int i = 0; i < files.length; i++) {
list(files[i]);//繼續列出
}
}
}
System.out.println(file);
}
}
執行緒阻塞問題
現在代碼都在main執行緒下執行,如果該程式執行完成后才能繼續執行下一條陳述句,要想解決這種耗時的問題,最好產生一個新的執行緒進行列出,
package com.day14.demo;import java.io.File;public class FileListDemo { public static void main(String[] args) { new Thread(()->{ File file = new File("f:" + File.separator); list(file); },"列出執行緒").start(); System.out.println("開始進行檔案資訊列出,,,,"); } public static void list(File file){ if(file.isDirectory()){ File[] files = file.listFiles(); if(files != null){ for (int i = 0; i < files.length; i++) { list(files[i]);//繼續列出 } } } System.out.println(file); }}
6、IO— 位元組流與字符流

字符流和位元組流最本質的區別就是只有一個位元組流是原生的操作,二字符流是經過處理后的操作,經過磁盤資料保存所保存的支持的資料型別只有:位元組,所有磁盤中的資料必須先讀到記憶體后才可以操作,記憶體里面會幫助我們把位元組變為字符,字符更加適合處理中文,
**位元組操作流:**OutputStream,InputStream;
**字符操作流:**Writer,Reader,
但是不管是位元組流還是字符流的操作,本身都表示資源操作,而執行所有的資源都會按照如下幾個步驟進行,下面以檔案操作為例(對檔案進行讀,寫操作):
- 要根據檔案創建File物件
- 根據位元組流或字符流的子類實體化我們的父類物件
- 進行資料的讀取、寫入操作
- 關閉流(clone())
對于IO操作屬于資源處理,所有的對于資源的處理進行處理完成后必須進行關閉,否則資源就再也無法執行,
6.1 位元組輸出流:OutputStream
Java.io.OutputStream主要的功能是進行位元組資料的輸出的,而這個類的定義如下:
public abstract class OutputStream extends Object implements Closeable, Flushable
發現OutputStream類定義的時候實作了兩個介面:Closeable,Flushable,這兩個介面定義如下:
| Closeable: | Flushable: |
|---|---|
| public interface Closeable extends AutoCloseable{ public void close() throws IOException; } | public interface Closeable{ public void flush() throws IOException; } |
當取得了OutputStream類實體化物件之后,下面肯定要進行輸出操作,在OutputStream類之中定義了三個方法:
**輸出單個位元組陣列資料:**public abstract void write(int b) throws IOException
**輸出一組位元組陣列資料:**public void write(byte[] b) throws IOException
**輸出部分位元組陣列資料:**public void write(byte[] b,int off,int len) throws IOException
提示:對于Closeable繼承的AutoCloseable介面
AuotCloseable實在JDK1.7的時候又增加了一個新的介面,但是這個介面的定義和Closeable定義是完全一樣的,我個人認為:有可能在一些其他的類上出現了自動的關閉功能,Closeable是手工關閉,AutoCloseable屬于自動關閉,
但是對于Closeable和Flushable這兩個介面實話而言不需要關注,因為從最早的習慣對于flush()和close()連個方法都是直接在OutputStream類之中定義的,所以很少去關心這些父介面問題,
對于OutputStream類而言發現其本身定義的是一個抽象類(abstract class),按照抽象類的使用原則來講,如果要想為父類實體化,那么就需要使用子類,就需要定義抽象的子類,而現在如果要執行的是檔案操作,則可以使用FileOutputStream子類完成,如果按照面向物件的開發原則,子類要為抽象類進行物件的實體化,而后呼叫的方法以父類中定義的方法為主,而具體的實作找實體化這個父類的子類完成,也就是說在整個的操作之中,用戶最關心的只有子類的構造方法:
**實體化FileOutputStream(新建資料):**public FileOutputStream([File file) throws FileNotFoundException
**實體化FileOutputStream(追加資料):**public FileOutputStream(File file,boolean append) throws FileNotFoundException

實作檔案內容的輸出
package com.day14.demo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class OutputDemo {
public static void main(String[] args) throws Exception {
//1.定義檔案路徑
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.getParentFile().exists()){//父路徑不存在
file.getParentFile().mkdirs();//創建父目錄
}
//2.要輸出的資料
String str = "Hello,zsr!!!!";
//3.實體化物件
FileOutputStream stream = new FileOutputStream(file);
//4.將內容寫進stream
stream.write(str.getBytes());//輸出資料,要將輸出的資料變為位元組陣列輸出
//5.關閉流
stream.close();
}
}
這里默認執行時進行檔案內容的覆寫,如果不希望進行檔案內容的覆寫可以直接將FileOutputStream改為
FileOutputStream stream = new FileOutputStream(file,true);
如果對寫入的內容需要換行操作必須使用\r\n進行換行操作,
6.2 位元組輸入流:InputStream
如果現在要從指定的資料源之中讀取資料,使用InputStream,而這個類的定義如下:
public abstract class InputStreamextends Objectimplements Closeable
發現InputStream只實作了Closeable介面
在InputStream之中定義了三個讀取資料的方法:
**讀取單個位元組:**public abstract int read() throws IOException
**說明:**每次執行read()方法都會讀取一個資料源的指定資料,如果現在發現已經讀取到了結尾則回傳-1.
**讀取多個位元組:**public int read(byte[] b) throws IOException
**說明:**如果現在要讀取的資料小于開辟的位元組陣列,這個時候read()方法的回傳值int回傳的是資料個數;如果現在開辟的位元組陣列小于讀取的長度,則這個時候回傳就是長度;如果資料已經讀完了,則這個時候的int回傳的是-1.
**讀取指定多個位元組:**public int read(byte[] b,int off,int len) throws IOException
**說明:**每次只讀取傳遞陣列的部分內容,如果讀取滿了,回傳就是長度;如果沒有讀取滿,回傳的就是讀取的個數;如果讀取到最后沒有資料了,就回傳-1

既然InputStream為抽象類,那么這個抽象類要使用就必須有子類,現在是通過檔案讀取內容,肯定使用FileInputStream子類進行操作,與OutputStream類的使用一樣,對于FileInputStream也只關心構造方法:
**FileInputStream****類構造方法:public FileInputStream(File file) throws FileNotFoundException
檔案資訊的讀取
package com.day14.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class InputDemo {
public static void main(String[] args) throws Exception {
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.exists()){
System.out.println("指定檔案不存在!!");
}else{
FileInputStream is = new FileInputStream(file);
byte[] result = new byte[1024];
int length = is.read(result);
System.out.println("讀取的內容為:" + new String(result,0,length));
}
}
}
6.3 字符輸出流:Writer
Writer類也是一個專門用來資料輸出的操作類,對于中文資料來說是比較友好的,這個類定義:
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
在Writer類之中定義的writer()方法都是以字符資料為主,但是在這些方法之中,只關心一個:
**輸出一個字串:**public void write(String str) throws IOException
如果要操作檔案肯定使用FileWriter子類,
package com.day14.demo;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriterDemo {
public static void main(String[] args) throws IOException {
//1.定義檔案路徑
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.getParentFile().exists()){//父路徑不存在
file.getParentFile().mkdirs();//創建父目錄
}
//2.要輸出的資料
String str = "我正在學java這門課程!!!!\r\n";
//如果想要進行內容不覆寫的直接使用true就可以了
//FileWriter out = new FileWriter(file,true);
FileWriter out = new FileWriter(file);
out.write(str);
out.close();
}
}
6.4 字符輸入流:Reader
Reader是進行字符資料讀取的一個操作類,其定義:
public abstract class Reader
extends Object
implements Readable, Closeable
在Writer類之中存在了直接輸出一個字串資料的方法,可是在Reader類之中并沒有定義這樣的方法,只是定義了三個按照字串讀取的方法?為什么會這樣?
因為在使用OutputStream輸出資料的時候,其程式可以輸出的大小一定是程式可以承受的資料的大小,那么如果說使用InputStream讀取的時候,可能被讀取的資料非常大,那么如果一次性全讀進來,就會出現問題,所以只能一個一個的進行讀取,
Reader依然是抽象類,那么如果從檔案讀取,依然使用FileReader類
package com.day14.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadDemo {
public static void main(String[] args) throws IOException {
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.exists()){
System.out.println("指定檔案不存在!!");
}else{
FileReader reader = new FileReader(file);
char[] result = new char[1024];
int length = reader.read(result);
System.out.println("讀取的內容為:" + new String(result,0,length));
}
}
}
字符比位元組的好處就是在于字串資料的支持上,而這個好處還只是在Writer()類中體現,所以與位元組流相比,字符流的操作并不是對等的關系,
6.5 位元組流與字符流區別
通過我們一系統的分析,可以發現位元組流和字符流的代碼操作區別不大,如果從我們實際的使用,我們位元組流是優先考慮,只有再我們使用中文的時候才考慮使用字符流,因為所有的字符都需要通過記憶體緩沖來進行處理,

既然讀資料需要快取的處理,那么寫資料也同樣需要,如果使用字符流沒有進行重繪,那么我們的內容可能再快取之中,所以必須進行強制重繪才能得到完整的資料內容,
package com.day14.demo;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriterDemo {
public static void main(String[] args) throws IOException {
//1.定義檔案路徑
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.getParentFile().exists()){//父路徑不存在
file.getParentFile().mkdirs();//創建父目錄
}
//2.要輸出的資料
String str = "我正在學java這門課程!!!!\r\n";
//如果想要進行內容不覆寫的直接使用true就可以了
//FileWriter out = new FileWriter(file,true);
FileWriter out = new FileWriter(file);
out.write(str);
out.flush();
}
}
在以后的IO處理的時候,如果處理的是圖片、音樂、文字都可以使用位元組流,只有再處理中文的時候才會使用字符流,
7、轉換流
現在對于IO操作就存在了位元組流和字符流兩種操作,那么對于這兩種操作流之間也是可以進行轉換的,而轉換的操作類有兩個:
將位元組輸出流變為字符輸出流(OutputStream->Writer)——OutputStreamWriter;
將位元組輸入流變為字符輸入流(InputStream->Reader)——InputStreaReader,
| OutputStreamWriter | InputStreamReader |
|---|---|
| public class OutputStreamWriter extends Writer | public class InputStreamReader extends Reader |
| public OutputStreamWriter(OutputStream out) | public InputStreamReader(InputStream in) |

通過以上的繼承結構和構造方法可以清楚發現,既然OutputStreamWriter是Writer的子類,那么必然OutputStreamWriter可以通過Writer類執行物件的向上轉型進行接收,而同時這個OutputStreamWriter類的構造方法可以接收OutputStream,這樣就可以完成轉型,
將位元組輸出流變為字符輸出流
package com.day14.demo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class OutWriterDemo {
public static void main(String[] args) throws Exception {
//1.定義檔案路徑
File file = new File("f:" + File.separator + "test" + File.separator + "hello.txt");
if(!file.getParentFile().exists()){//父路徑不存在
file.getParentFile().mkdirs();//創建父目錄
}
//2.要輸出的資料
String str = "Hello,world!!!!";
//3.實體化物件
OutputStream stream = new FileOutputStream(file,true);
//4.將內容寫進stream
Writer out = new OutputStreamWriter(stream);
out.write(str);
//5.關閉流
out.close();
}
}
對于檔案操作可以使用FileInputStream,FileOutputStream,FileReader,FileWriter四個類,那么下面分別觀察這四個類的繼承結構,
觀察FileInputStream,FileOutoutStream類的繼承結構
| FileInputStream | FileOutoutStream |
|---|---|
| java.lang.Object java.io.InputStream java.io.FilterInputStream | java.lang.Object java.io.OutputStream java.io.FileOutputStream |
觀察FileReader,FileWriter類的繼承結構
| FileReader | FileWrite |
|---|---|
| java.lang.Object java.io.Reader java.io.InputStreamReader java.io.FileReader | java.lang.Object java.io.Writer java.io.OutputStreamWriter java.io.FileWriter |

通過以上的繼承關系也可以發現,實際上所有的字符資料都是需要進行轉換的,依靠轉換流完成,以后真正保存或者是傳輸的資料是不可能有字符的,全部都是位元組,而位元組只是在電腦之中處理后的結果,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/295160.html
標籤:java
