java io

来源:https://www.cnblogs.com/YiMingZhu/archive/2018/07/18/9332996.html
-Advertisement-
Play Games

http://www.cnblogs.com/baixl/p/4170599.html ...


 

主要內容

  • java.io.File類的使用
  • IO原理及流的分類
  • 文件流
  • FileInputStream / FileOutputStream / FileReader / FileWriter
  • 緩衝流
    • BufferedInputStream / BufferedOutputStream /
    • BufferedReader / BufferedWriter
  • 轉換流
  • InputStreamReader / OutputStreamWriter
  • 標準輸入/輸出流
  • 列印流(瞭解)
  • PrintStream / PrintWriter
  • 數據流(瞭解)
  • DataInputStream / DataOutputStream
  • 對象流 ----涉及序列化、反序列化
  • ObjectInputStream / ObjectOutputStream
  • 隨機存取文件流
  • RandomAccessFile

File類

  • java.io.File類:文件和目錄路徑名的抽象表示形式,與平臺無關
  • File 能新建、刪除、重命名文件和目錄,但 File 不能訪問文件內容本身。如果需要訪問文件內容本身,則需要使用輸入/輸出流。
  • File對象可以作為參數傳遞給流的構造函數
  • File類的常見構造方法:
    • public File(String pathname)

以pathname為路徑創建File對象,可以是絕對路徑或者相對路徑,如果pathname是相對路徑,則預設的當前路徑在系統屬性user.dir中存儲。

  • public File(String parent,String child)

以parent為父路徑,child為子路徑創建File對象。

  • File的靜態屬性String separator存儲了當前系統的路徑分隔符。
  • 在UNIX中,此欄位為'/',在Windows中,為'\\'

常見方法:

eg:

File dir1 = new File("D:/IOTest/dir1");

if (!dir1.exists()) { // 如果D:/IOTest/dir1不存在,就創建為目錄

    dir1.mkdir(); }

// 創建以dir1為父目錄,名為"dir2"的File對象

File dir2 = new File(dir1, "dir2");

if (!dir2.exists()) { // 如果還不存在,就創建為目錄

    dir2.mkdirs(); }

File dir4 = new File(dir1, "dir3/dir4");

if (!dir4.exists()) {

    dir4.mkdirs();

}

// 創建以dir2為父目錄,名為"test.txt"的File對象

File file = new File(dir2, "test.txt");     

if (!file.exists()) { // 如果還不存在,就創建為文件

    file.createNewFile();}

Java IO原理

  • IO流用來處理設備之間的數據傳輸。
  • Java程式中,對於數據的輸入/輸出操作以"流(stream)" 的方式進行。
  • java.io包下提供了各種"流"類和介面,用以獲取不同種類的數據,並通過標準的方法輸入或輸出數據。

流的分類

  • 按操作數據單位不同分為:位元組流(8 bit),字元流(16 bit)
  • 按數據流的流向不同分為:輸入流,輸出流
  • 按流的角色的不同分為:節點流,處理流

(抽象基類)

位元組流

字元流

輸入流

InputStream

Reader

輸出流

OutputStream

Writer

  1. Java的IO流共涉及40多個類,實際上非常規則,都是從如上4個抽象基類派生的。
  2. 由這四個類派生出來的子類名稱都是以其父類名作為子類名尾碼。
  3. 位元組流:以byte為單位傳輸
  4. 字元流:以char為單位傳輸

IO流體系

InputStream & Reader

  • InputStream 和 Reader 是所有輸入流的基類。
  • InputStream(典型實現:FileInputStream
    • int read()
    • int read(byte[] b)
    • int read(byte[] b, int off, int len)
  • Reader(典型實現:FileReader
    • int read()
    • int read(char [] c)
    • int read(char [] c, int off, int len)
  • 程式中打開的文件 IO 資源不屬於記憶體里的資源,垃圾回收機制無法回收該資源,所以應該顯式關閉文件 IO 資源

OutputStream & Writer

  • OutputStream 和 Writer 也非常相似:
    • void write(int b/int c);
    • void write(byte[] b/char[] cbuf);
    • void write(byte[] b/char[] buff, int off, int len);
    • void flush();
    • void close(); 需要先刷新,再關閉此流
  • 因為字元流直接以字元作為操作單位,所以 Writer 可以用字元串來替換字元數組,即以 String 對象作為參數
    • void write(String str);
    • void write(String str, int off, int len);

文件流

讀取文件

1.建立一個流對象,將已存在的一個文件載入進流。

  • FileReader fr = new FileReader("Test.txt");

2.創建一個臨時存放數據的數組。

  • char[] ch = new char[1024];

3.調用流對象的讀取方法將流中的數據讀入到數組中。

  • fr.read(ch);

FileReader fr = null;

    try{

        fr = new FileReader("c:\\test.txt");

        char[] buf = new char[1024];

        int len= 0;

        while((len=fr.read(buf))!=-1){

            System.out.println(new String(buf ,0,len));}

    }catch (IOException e){

        System.out.println("read-Exception :"+e.toString());}

    finally{

        if(fr!=null){

            try{

                fr.close();

            }catch (IOException e){

        System.out.println("close-Exception :"+e.toString());

            } } }

 

寫入文件

1.創建流對象,建立數據存放文件

  • FileWriter fw = new FileWriter("Test.txt");

2.調用流對象的寫入方法,將數據寫入流

  • fw.write("text");

3.關閉流資源,並將流中的數據清空到文件中。

  • fw.close();

FileWriter fw = null;

    try{

        fw = new FileWriter("Test.txt");

        fw.write("text");

    }

    catch (IOException e){

        System.out.println(e.toString());

    }

    finally{

        If(fw!=null)

        try{

         fw.close();

        }

        catch (IOException e){

            System.out.println(e.toString());

}    

}

 

註意點:

  • 定義文件路徑時,註意:可以用"/"或者"\\"。File.separator()
  • 在寫入一個文件時,如果目錄下有同名文件將被覆蓋。
  • 在讀取文件時,必須保證該文件已存在,否則出異常。

 

處理流之一:緩衝流

  • 為了提高數據讀寫的速度,Java API提供了帶緩衝功能的流類,在使用這些流類時,會創建一個內部緩衝區數組
  • 根據數據操作單位可以把緩衝流分為:
  • BufferedInputStream 和 BufferedOutputStream
  • BufferedReader 和 BufferedWriter
  • 緩衝流要"套接"在相應的節點流之上,對讀寫的數據提供了緩衝的功能,提高了讀寫的效率,同時增加了一些新的方法
  • 對於輸出的緩衝流,寫出的數據會先在記憶體中緩存,使用flush()將會使記憶體中的數據立刻寫出

     

BufferedReader br = null;

BufferedWriter bw = null;

try {

    //step1:創建緩衝流對象:它是過濾流,是對節點流的包裝

    br = new BufferedReader(newFileReader("d:\\IOTest\\source.txt"));

    bw = new BufferedWriter(newFileWriter("d:\\IOTest\\destBF.txt"));

    String str = null;

    while ((str = br.readLine()) != null) { //一次讀取字元文本文件的一行字元

        bw.write(str); //一次寫入一行字元串

        bw.newLine(); //寫入行分隔符

    }

    bw.flush(); //step2:刷新緩衝區

catch (IOException e) {

    e.printStackTrace();

}

finally {

// step3: 關閉IO流對象

try {

    if (bw != null) {

        bw.close(); //關閉過濾流時,會自動關閉它所包裝的底層節點流

    }

catch (IOException e) {

    e.printStackTrace();

}

try {

    if (br != null) {

        br.close();

    }

catch (IOException e) {

    e.printStackTrace();

    }

}

處理流之二:轉換流

  • 轉換流提供了在位元組流和字元流之間的轉換
  • Java API提供了兩個轉換流:
    • InputStreamReader和OutputStreamWriter
  • 位元組流中的數據都是字元時,轉成字元流操作更高效。

InputStreamReader

  • 用於將位元組流中讀取到的位元組按指定字元集解碼成字元。需要和InputStream"套接"。
  • 構造方法
  • public InputStreamReader(InputStream in)
  • public InputSreamReader(InputStream in,String charsetName)

如: Reader isr = new

InputStreamReader(System.in,"ISO5334_1");//指定字元集

OutputStreamWriter

  • 用於將要寫入到位元組流中的字元按指定字元集編碼成位元組。需要和OutputStream"套接"。
  • 構造方法
  • public OutputStreamWriter(OutputStream out)
  • public OutputStreamWriter(OutputStream out,String charsetName)

public void testMyInput() throws Exception{

FileInputStream fis = new FileInputStream("dbcp.txt");

FileOutputStream fos = new FileOutputStream("dbcp5.txt");

InputStreamReader isr = new InputStreamReader(fis,"GBK");

OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");

BufferedReader br = new BufferedReader(isr);

BufferedWriter bw = new BufferedWriter(osw);

String str = null;

while((str = br.readLine()) != null){

bw.write(str);

bw.newLine();

bw.flush();

} bw.close(); br.close();}

補充:字元編碼

  • 編碼表的由來

電腦只能識別二進位數據,早期由來是電信號。為了方便應用電腦,讓它可以識別各個國家的文字。就將各個國家的文字用數字來表示,並一一對應,形成一張表。這就是編碼表。

  • 常見的編碼表
  • ASCII:美國標準信息交換碼。
    • 用一個位元組的7位可以表示。
  • ISO8859-1:拉丁碼表。歐洲碼表
    • 用一個位元組的8位表示。
  • GB2312:中國的中文編碼表。
  • GBK:中國的中文編碼表升級,融合了更多的中文文字元號。
  • Unicode:國際標準碼,融合了多種文字。
    • 所有文字都用兩個位元組來表示,Java語言使用的就是unicode
  • UTF-8:最多用三個位元組來表示一個字元。
  • 編碼:字元串à位元組數組
  • 解碼:位元組數組à字元串
  • 轉換流的編碼應用
  • 可以將字元按指定編碼格式存儲。
  • 可以對文本數據按指定編碼格式來解讀。
  • 指定編碼表的動作由構造器完成。

處理流之三:標準輸入輸出流

  • System.in和System.out分別代表了系統標準的輸入和輸出設備
  • 預設輸入設備是鍵盤,輸出設備是顯示器
  • System.in的類型是InputStream
  • System.out的類型是PrintStream,其是OutputStream的子類FilterOutputStream 的子類
  • 通過System類的setIn,setOut方法對預設設備進行改變。

 

System.out.println("請輸入信息(退出輸入e或exit):");

//把"標準"輸入流(鍵盤輸入)這個位元組流包裝成字元流,再包裝成緩衝流

BufferedReader br = new BufferedReader(

    new InputStreamReader(System.in));

String s = null;

try {

    while ((s = br.readLine()) != null) { //讀取用戶輸入的一行數據 --> 阻塞程式

        if (s.equalsIgnoreCase("e") || s.equalsIgnoreCase("exit")) {

            System.out.println("安全退出!!");

            break;

        }

        //將讀取到的整行字元串轉成大寫輸出

        System.out.println("-->:"+s.toUpperCase());

        System.out.println("繼續輸入信息");

    }    

catch (IOException e) {

        e.printStackTrace();

finally {

    try {

        if (br != null) {

            br.close(); //關閉過濾流時,會自動關閉它包裝的底層節點流

        }    

    } catch (IOException e) {

        e.printStackTrace();

    }    

}

 

        

處理流之四:列印流(瞭解)

  • 在整個IO包中,列印流是輸出信息最方便的類。
  • PrintStream(位元組列印流)PrintWriter(字元列印流)
    • 提供了一系列重載的print和println方法,用於多種數據類型的輸出
    • PrintStream和PrintWriter的輸出不會拋出異常
    • PrintStream和PrintWriter有自動flush功能
    • System.out返回的是PrintStream的實例

 

FileOutputStream fos = null;

    try {

        fos = new FileOutputStream(new File("D:\\IO\\text.txt"));

    } catch (FileNotFoundException e) {

        e.printStackTrace();

    }//創建列印輸出流,設置為自動刷新模式(寫入換行符或位元組 '\n' 時都會刷新輸出緩衝區)

    PrintStream ps = new PrintStream(fos,true);

    if (ps != null) {    // 把標準輸出流(控制台輸出)改成文件

        System.setOut(ps);}

    for (int i = 0; i <= 255; i++) { //輸出ASCII字元

        System.out.print((char)i);

        if (i % 50 == 0) { //每50個數據一行

            System.out.println(); // 換行

        }

    }

    ps.close();

}

 

處理流之五:數據流(瞭解)

  • 為了方便地操作Java語言的基本數據類型的數據,可以使用數據流。
  • 數據流有兩個類:(用於讀取和寫出基本數據類型的數據)
    • DataInputStream 和 DataOutputStream
    • 分別"套接"在 InputStream 和 OutputStream 節點流上
  • DataInputStream中的方法

boolean readBoolean()        byte readByte()

char readChar()            float readFloat()

double readDouble()        short readShort()

long readLong()            int readInt()

String readUTF() void readFully(byte[] b)

  • DataOutputStream中的方法
  • 將上述的方法的read改為相應的write即可。

 

DataOutputStream dos = null;

    try {    //創建連接到指定文件的數據輸出流對象

        dos = new DataOutputStream(new FileOutputStream(

                    "d:\\IOTest\\destData.dat"));

            dos.writeUTF("ab中國"); //寫UTF字元串

            dos.writeBoolean(false); //寫入布爾值

            dos.writeLong(1234567890L); //寫入長整數

            System.out.println("寫文件成功!");

        } catch (IOException e) {

            e.printStackTrace();

        } finally {    //關閉流對象

            try {

            if (dos != null) {

            // 關閉過濾流時,會自動關閉它包裝的底層節點流

            dos.close();

            }

        } catch (IOException e) {

            e.printStackTrace();

        }    }

處理流之六:對象流

  • ObjectInputStream和OjbectOutputSteam
  • 用於存儲和讀取對象的處理流。它的強大之處就是可以把Java中的對象寫入到數據源中,也能把對象從數據源中還原回來。
  • 序列化(Serialize):用ObjectOutputStream類將一個Java對象寫入IO流中
  • 反序列化(Deserialize):用ObjectInputStream類從IO流中恢復該Java對象
  • ObjectOutputStream和ObjectInputStream不能序列化static和transient修飾的成員變數

對象的序列化

  • 對象序列化機制允許把記憶體中的Java對象轉換成平臺無關的二進位流,從而允許把這種二進位流持久地保存在磁碟上,或通過網路將這種二進位流傳輸到另一個網路節點。當其它程式獲取了這種二進位流,就可以恢覆成原來的Java對象
  • 序列化的好處在於可將任何實現了Serializable接口的對象轉化為位元組數據,使其在保存和傳輸時可被還原
  • 序列化是 RMI(Remote Method Invoke – 遠程方法調用)過程的參數和返回值都必須實現的機制,而 RMI 是 JavaEE 的基礎。因此序列化機制是 JavaEE 平臺的基礎
  • 如果需要讓某個對象支持序列化機制,則必須讓其類是可序列化的,為了讓某個類是可序列化的,該類必須實現如下兩個介面之一:
    • Serializable
    • Externalizable
  • 凡是實現Serializable介面的類都有一個表示序列化版本標識符的靜態變數:
    • private static final long serialVersionUID;
    • serialVersionUID用來表明類的不同版本間的相容性
    • 如果類沒有顯示定義這個靜態變數,它的值是Java運行時環境根據類的內部細節自動生成的。若類的源代碼作了修改,serialVersionUID 可能發生變化。故建議,顯示聲明
  • 顯示定義serialVersionUID的用途
    • 希望類的不同版本對序列化相容,因此需確保類的不同版本具有相同的serialVersionUID
    • 不希望類的不同版本對序列化相容,因此需確保類的不同版本具有不同的serialVersionUID

使用對象流序列化對象

  • 若某個類實現了 Serializable 介面,該類的對象就是可序列化的:
    • 創建一個 ObjectOutputStream
    • 調用 ObjectOutputStream 對象的 writeObject(對象) 方法輸出可序列化對象。註意寫出一次,操作flush()
  • 反序列化
    • 創建一個 ObjectInputStream
    • 調用 readObject() 方法讀取流中的對象
  • 強調:如果某個類的欄位不是基本數據類型或 String 類型,而是另一個引用類型,那麼這個引用類型必須是可序列化的,否則擁有該類型的 Field 的類也不能序列化

 

序列化:將對象寫入到磁碟或者進行網路傳輸。

要求對象必須實現序列化

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test3.txt"));

Person p = new Person("韓梅梅",18,"中華大街",new Pet());

oos.writeObject(p);

oos.flush();

oos.close();

//反序列化:將磁碟中的對象數據源讀出。

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test3.txt"));

Person p1 = (Person)ois.readObject();

System.out.println(p1.toString());

ois.close();

 

RandomAccessFile 類

  • RandomAccessFile 類支持 "隨機訪問" 的方式,程式可以直接跳到文件的任意地方來讀、寫文件
    • 支持只訪問文件的部分內容
    • 可以向已存在的文件後追加內容
  • RandomAccessFile 對象包含一個記錄指針,用以標示當前讀寫處的位置。RandomAccessFile 類對象可以自由移動記錄指針:
    • long getFilePointer():獲取文件記錄指針的當前位置
    • void seek(long pos):將文件記錄指針定位到 pos 位置
  • 構造器
  • 創建 RandomAccessFile 類實例需要指定一個 mode 參數,該參數指定 RandomAccessFile 的訪問模式:
    • r: 以只讀方式打開
    • rw:打開以便讀取和寫入
    • rwd:打開以便讀取和寫入;同步文件內容的更新
    • rws:打開以便讀取和寫入;同步文件內容和元數據的更新

 

讀取文件內容

RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");    

raf.seek(5);

    byte [] b = new byte[1024];

    int off = 0;

    int len = 5;

    raf.read(b, off, len);

        

    String str = new String(b, 0, len);

    System.out.println(str);

        

    raf.close();

寫入文件內容

 

RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");

    raf.seek(5);

        

    //先讀出來

    String temp = raf.readLine();

        

    raf.seek(5);

    raf.write("xyz".getBytes());

    raf.write(temp.getBytes());

        

    raf.close();

流的基本應用小節

  • 流是用來處理數據的。
  • 處理數據時,一定要先明確數據源,與數據目的地
    • 數據源可以是文件,可以是鍵盤。
    • 數據目的地可以是文件、顯示器或者其他設備。
  • 而流只是在幫助數據進行傳輸,並對傳輸的數據進行處理,比如過濾處理、轉換處理等。

 

 

  • 位元組流-緩衝流(重點)
  • 輸入流InputStream-FileInputStream-BufferedInputStream
  • 輸出流OutputStream-FileOutputStream-BufferedOutputStream
  • 字元流-緩衝流(重點)
  • 輸入流Reader-FileReader-BufferedReader
  • 輸出流Writer-FileWriter-BufferedWriter
  • 轉換流
  • InputSteamReader和OutputStreamWriter
  • 對象流ObjectInputStream和ObjectOutputStream(難點)
  • 序列化
  • 反序列化
  • 隨機存取流RandomAccessFile(掌握讀取、寫入)

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上次知識回顧:https://www.cnblogs.com/dotnetcrazy/p/9278573.html 代碼褲子:https://github.com/lotapp/BaseCode 線上編程:https://mybinder.org/v2/gh/lotapp/BaseCode/mast ...
  • 引言 上一篇文章聊到了Java記憶體模型,在其中我們說JMM是建立在happens before(先行發生)原則之上的。 為什麼這麼說呢?因為在Java程式的執行過程中,編譯器和處理器對我們所寫的代碼進行了一系列的優化來提高程式的執行效率。這其中就包括對指令的“重排序”。 重排序導致了我們代碼並不會按 ...
  • goroutine只是由官方實現的超級"線程池"而已,每個實例4 5kb的棧記憶體占用和用於實現機制而大幅減少的創建和銷毀開銷。 併發不是並行(多CPU): 併發主要由切換時間片來實現"同時"運行,並行則是直接利用多核實現多線程的運行,但Go可以設置使用核數,以發揮多核電腦的能力。 通過go關鍵字實 ...
  • MIPS架構下的MCU,指令集包含R-Type、I-Type、J-Type三種,在數電課程設計時為了給MCU編寫指令集,需要將彙編語言轉化成機器代碼,這裡分享一下自己寫的Matlab 的 GUI。 主函數 C2M 函數rig_f 用來尋找名稱對應的寄存器地址 函數rig_n 用來將5位十進位數轉換成 ...
  • 原創 The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 48698 Accepted: 23286 Description Severe acute respiratory syndrome (SARS), ...
  • 1. 學習計劃 第二天:商品列表功能實現 1、服務中間件dubbo 2、工程改造為基於soa架構 3、商品列表查詢功能實現。 2. 將工程改造為SOA架構 2.1. 分析 由於宜立方商城是基於soa的架構,表現層和服務層是不同的工程。所以要實現商品列表查詢需要兩個系統之間進行通信。 如何實現遠程通信 ...
  • provider pom 連接註冊器register需要applicationContext需要web.xml載入配置文件監聽器 註冊 介面 實現類 註意這個@Service是dubbo的Service 右擊maven項目run as選maven build.. 輸入tomcat7:run 啟動這個 ...
  • w2 16、第二周-第02章節-Python3.5-模塊初識 sys模塊 sys.path sys.argv os模塊 os.system os.popen os.mkdir 17、第二周-第03章節-Python3.5-模塊初識2 18、第二周-第04章節-Python3.5-pyc是什麼 19、 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...