Java入門——(7)IO(輸入與輸出)

来源:http://www.cnblogs.com/gdwkong/archive/2017/11/04/7775013.html
-Advertisement-
Play Games

本文從IO流的繼承體系方面做了簡要的說明,並對常見的IO流進行了介紹並提供了簡單的實例。 ...


 

  IO流位於java.io包中,根據操作數據不同,分為位元組流和字元流;根據數據輸入方面的不同又可分為輸入流和輸出流,無論是何種流,最終都依賴於操作系統。 一、位元組流: 1、位元組流,主要用於圖片、音頻、視頻的傳輸,以二進位的形式進行,分為位元組輸入流和位元組輸出流;位元組流操作的是位元組數組;字元流操作的是字元數組。 2、位元組輸入與位元組輸出流的繼承體系圖 

../../Mac/Desktop/InputStream繼承體系.png ../../Mac/Desktop/OutputStream繼承體系.png 3、InputStream 與OutputStream常用方法  
InputStream 常用方法
方法聲明 功能描述
int read() 從輸入流讀取一個8位的位元組,把它轉換為0-255之間的整數,並返回這一整數
int read(byte[] b) 從輸入流讀取若幹位元組,把它們保存到參數b指定的位元組數組中,返回的整數表示讀取的位元組數
int read(byte[] b,int off,len) 從輸入流讀取若幹位元組,把它們保存到參數b指定的位元組數組中,off指定位元組數組開始保存數據的起始下標,len表示讀取的位元組
void close() 關閉此輸入流並釋放與該流關聯的所有系統資源
 
OutputStream 常用方法
方法聲明 功能描述
void write(int b) 向輸出流寫入一個位元組
void write(byte[]  b) 把參數b指定的位元組數組的所有位元組寫到輸出流
void write(byte[] b,int off,len) 將指定byte數組中從偏移量off開始的len個位元組寫入輸出流
void flush() 刷新此輸出流並強制寫出所有緩衝的輸出位元組
void close() 關閉此輸出流並釋放與該流關聯的所有系統資源
  4、位元組流讀寫文件:   FileInputStream 是操作文件的的位元組輸入流,專門用於讀取文件中的數據。   FileOutputStream是操作文件的的位元組輸出流,專門用於把數據寫入文件。            示例:
 1 public class Example01 {
 2     public static void main(String[] args) throws Exception{
 3         //創建一個文件位元組型輸入流
 4         InputStream inputStream = new FileInputStream("test.txt");
 5         int b = 0;  //定義一個int類型的變數b,記住每一次讀取的一個位元組
 6         while (true){
 7             b=inputStream.read();//變數b記住讀取的一個位元組
 8             if(b==-1){     //如果讀取的位元組為-1,跳出while迴圈
 9                 break;
10             }
11             System.out.println(b); //否則將b寫出
12         }
13         inputStream.close();
14       
15         //創建一個文件位元組輸出流
16         OutputStream OutputStream= new FileOutputStream("example.txt",true);
17         String string = "人之初";
18         byte [] bytes= string.getBytes();
19         for (int i = 0;i<bytes.length;i++){
20             OutputStream.write(bytes[i]);
21         }
22         OutputStream.close();
23     }
24 }
View Code   文件拷貝:
 1 public class Example04 {
 2        public static void main(String[] args) throws Exception{
 3            //創建一個位元組輸入流,用於讀取當前目錄下source文件中的docx文件
 4            InputStream in = new FileInputStream("source/IO工具包.mp4") ;
 5            //創建一個文件位元組輸出流,用於將讀取的數據寫入target目錄下的文件中
 6            OutputStream out = new FileOutputStream("target/IO工具包.mp4");
 7            byte [] buff = new byte[1024]; //定義一個位元組數組,作為緩衝區
 8            int len;  //定義一個int類型的變數len記住讀取讀入緩衝區的位元組數
 9            // int len = 0 ; //定義一個int類型變數,記住每次讀取的一個位元組
10            long begintime = System.currentTimeMillis();
11               while ((len=in.read(buff))!=-1){  //判斷是否讀到文件末尾
12                   out.write(buff,0,len);  //從第一位元組開始,向文件寫入len個位元組
13               }
14            long endtime = System.currentTimeMillis();
15            System.out.println("耗時"+(endtime-begintime)+"毫秒");
16            in.close();
17            out.close();
18        }
19 }
View Code 5、裝飾設計模式思想:
TextReader:讀取文本; MediaReader:讀取媒體數據; 抽取共性,形成體系。 Reader |---TextReader  read() |---MediaReader 需求1: 提高讀取文本的效率,使用緩衝技術,提供一個讀取文本更高效的讀取方法。 覆蓋TextReader中的方法。建立高效的read方法。所以建立一個TextReader的子類,用於高效的讀取。 Reader |---TextReader  read()     |--BufferedTextReader      |---MediaReader 需求2: 提高讀取媒體數據的效率,派生一個高效的子類,用於高效的讀取。 Reader |---TextReader  read()     |--BufferedTextReader      |---MediaReader          |--BufferedMediaReader   發現一個小問題,如果Reader中還有讀取其他數據的子類,如果要高效,那豈不是還要給這個子類添加一個高效子類? 是的,為了給具體的讀取數據的對象增加一些功能,是需要通過子類來完成的。 但是這樣做,會導致這個繼承體系很臃腫!僅僅為了增加一些功能,而進行繼承,不建議的。 這些子類無非就是需要高效,而且這些高效的功能實現是一致的。就是提供一個緩衝區而以。 乾脆,單獨定義一個具備這個緩衝功能的對象,哪個子類需要被緩衝,就將哪個子類傳遞進來。 class BufferedReader  extends Reader{ private [];//提供數據 BufferedReader(Reader r){    //對Reader高效就行 } read(){操作的是數組}  //高效的讀取動作 } 此時繼承體系: Reader |---TextReader       |---MediaReader      |---BufferedReader 發現這種設計方式減少了繼承體系的臃腫,增減功能,比繼承更為靈活。 這種設計方式稱為:裝飾設計模式。 解決問題:給一組類增加功能,避免繼承的臃腫,提高靈活。 註意:裝飾類和被裝飾類必須屬於同一體系,通常裝飾類都會提供構造函數接收被裝飾類對象。裝飾類通常不單獨存在。
6、位元組緩衝流   使用的是裝飾設計模式   示例:
 1 public class Example07 {
 2     public static void main(String[] args) throws Exception{
 3         //創建一個帶緩衝區的輸入流
 4         BufferedInputStream bis = new BufferedInputStream(
 5                 new FileInputStream("src.txt"));
 6         //創建一個帶緩衝區的輸出流
 7         BufferedOutputStream bos = new BufferedOutputStream(
 8                 new FileOutputStream("des.txt"));
 9         int len;
10         while ((len=bis.read())!=-1){
11             bos.write(len);
12         }
13         bis.close();
14         bos.close();
15     }
16 }
View Code 二、字元流 1、字元流:為了便於操作數據中的字元數據。原理:位元組流+編碼表。 2、字元流繼承體系

 


../Mac/Desktop/Reader繼承體系.png ../Mac/Desktop/Writer繼承體系.png 3、基類方法摘要
Reader方法摘要
abstract  void close()   關閉該流並釋放與之關聯的所有資源。
void mark(int readAheadLimit)  標記流中的當前位置。
boolean markSupported()  判斷此流是否支持 mark() 操作。
int read()  讀取單個字元。
int read(char[] cbuf)  將字元讀入數組。
abstract  int read(char[] cbuf, int off, int len)  將字元讀入數組的某一部分。
int read(CharBuffer target)  試圖將字元讀入指定的字元緩衝區。
boolean ready()  判斷是否準備讀取此流。
void reset()  重置該流。
long skip(long n)  跳過字元。
   
Writer方法摘要
void close()  關閉此流,但要先刷新它。
void flush()  刷新該流的緩衝。
String getEncoding()  返回此流使用的字元編碼的名稱。
void write(char[] cbuf, int off, int len)  寫入字元數組的某一部分。
void write(int c)  寫入單個字元。
void write(String str, int off, int len)  寫入字元串的某一部分。
flush()和close()的區別? flush();將流中的緩衝區緩衝中的數據刷新到目的地中,刷新後,流還可以繼續使用; close();關閉資源,但在關閉前會將緩衝區中的數據刷新到目的地,否則丟失數據,然後再關閉流,流不可以使用。 如果寫入數據多,一邊寫一邊刷新,最後一次可以不刷新,由close()完成刷新並關閉。
4、字元流操作文件   FileReader 和FileWriter 用於讀寫文件;BufferedReader 和BufferdeWriter是具有緩衝功能的流,可以提高讀寫效率。   BufferedReader中有一重要的方法readLind(),該方法用於一次讀取一行文本。
 1 public class Example10 {
 2     public static void main(String[] args) throws Exception{
 3         FileReader reader = new FileReader("src.txt");
 4         //創建一個BufferedReader緩衝對象
 5         BufferedReader br = new BufferedReader(reader);
 6         FileWriter writer = new FileWriter("des.txt");
 7         //創建一個BufferedWriter緩衝對象
 8         BufferedWriter bw = new BufferedWriter(writer);
 9         String string;
10         while ((string=br.readLine())!=null){
11             bw.write(string);
12             bw.newLine();//寫入一個換行符,該方法會根據不同的操作系統生成相應的換行符
13         }
14         br.close();
15         bw.close();
16     }
17 }
View Code

  BufferedReader一直接子類——LineNumberReader ,一個可以跟蹤行號的輸入流。

 1 public class Example11 {
 2     public static void main(String[] args) throws Exception{
 3         FileReader fr = new FileReader("/Users/Shared/第八章IO練習/exampele09.txt"); //創建字元輸入流
 4         FileWriter fw = new FileWriter("copy.txt");//創建字元輸出流
 5         LineNumberReader lr = new LineNumberReader(fr);  //包裝
 6         lr.setLineNumber(0);  //設置讀取文件的起始行號
 7         String line = null;
 8         while ((line=lr.readLine())!=null){
 9             fw.write(lr.getLineNumber()+":"+line);//將行號寫入到文件中
10             fw.write("\r\n");  //寫入換行
11         }
12         lr.close();
13         fw.close();
14     }
15 }
View Code 5、轉換流         轉換流是一種字元流,只能實現位元組流讀寫文本數據的時候,通過轉換流來使用字元高效流的方法。而不能實現圖片、音頻等數據的讀寫。    InputStreamReader:理解上是位元組流通向字元流的橋梁,使用上為:
  BufferedReader  br = new BufferedReader(new InputStreamReader(System.in));
   OutputStreamWriter:理解上是字元流通向位元組流的橋梁,使用上還是通過位元組流轉成字元流:
BufferedWriter  bw = new BufferedWriter (new OutputStreamWriter(System.out));
 1 public class Example12 {
 2     public static void main(String[] args) throws Exception{
 3         FileInputStream in= new FileInputStream("src1.txt");//創建位元組輸入流
 4         InputStreamReader isr = new InputStreamReader(in);//將位元組流輸入轉換成字元輸入流
 5         BufferedReader br = new BufferedReader(isr);//對字元流對象進行包裝
 6         FileOutputStream out = new FileOutputStream("des1.txt");
 7         //將位元組流轉換為字元輸出流
 8         OutputStreamWriter osw = new OutputStreamWriter(out);
 9         //對字元輸出流對象進行包裝
10         BufferedWriter bw = new BufferedWriter(osw);
11         String line;
12         while ((line=br.readLine())!=null){  //判斷是否讀到文件末尾
13             bw.write(line);  //輸出讀取到文件
14         }
15         br.close();
16         bw.close();
17     }
18 }
View Code

三、其他IO流

1、ObjectOutputStream、ObjectInputStream   序列化:把對象按照流一樣的方式傳輸或者存儲。(ObjectOutputStream).          當對象進行序列化時,必須保證該對象實現Serializable介面,否則程式會出現NotSerializableException異常。   反序列號:把網路中的流數據或者文件中的流數據(二進位數據)還原成對象。(ObjectInputStream).
 1 public class Example13 {
 2     public static void main(String[] args) throws Exception{
 3         //序列化對象
 4         Person person = new Person("p1","zhangsan",20);
 5         //創建文件輸出流對象,將數據寫入objectStream.txt
 6         FileOutputStream fos = new FileOutputStream("objectStream.txt");
 7         //創建對象輸出流對象,用於處理輸出流對象寫入的數據
 8         ObjectOutputStream oos = new ObjectOutputStream(fos);
 9         //將Person對象輸出到輸出流中
10         oos.writeObject(person);
11         oos.close();
12  
13         //反序列化對象
14         FileInputStream fis = new FileInputStream("object.txt");
15         //創建文件輸入流對象,用於讀取指定文件的數據
16         ObjectInputStream ois = new ObjectInputStream(fis);
17         //創建對象輸入流,並且從指定的輸入流中過讀取數據
18         Object p = ois.readObject();
19         System.out.println(p);
20         ois.close();
21     }
22 }
23 class Person implements Serializable{
24     private String id;
25     private String name;
26     private int age;
27     public Person(String id, String name, int age) {
28         super();
29         this.id = id;
30         this.name = name;
31         this.age = age;
32     }
33     public String getId() {
34         return id;
35     }
36     public String getName() {
37         return name;
38     }
39     public int getAge() {
40         return age;
41     }
42 }
View Code 2、DataInputStream,DataOutputStream         有時候並不需要存儲整個對象的信息,而只需要存儲對象的成員數據,這些成員數據的類型又都是基本數據類型,可使用數據操作流:DataInputStream,DataOutputStream 。
 1 public class Example15 {
 2     public static void main(String[] args) throws Exception{
 3         BufferedOutputStream  bos = new BufferedOutputStream(
 4                 new FileOutputStream("/Users/Shared/ioexample/dataStream.txt"));
 5         DataOutputStream dos = new DataOutputStream(bos);
 6         dos.writeByte(12);                  //寫一個位元組
 7         dos.writeChar('1');                 //寫一個字元
 8         dos.writeBoolean(true);             //寫一個布爾值
 9         dos.writeUTF("同學,你好");          //寫一個轉換成UTF-8的字元串
10         dos.close();                           //關閉流
11         BufferedInputStream bis= new BufferedInputStream(
12                 new FileInputStream("/Users/Shared/ioexample/dataStream.txt"));
13         DataInputStream dis = new DataInputStream(bis);
14         System.out.println(dis.readByte());     //讀取一個位元組
15         System.out.println(dis.readChar());     //讀取一個字元
16         System.out.println(dis.readBoolean());  //讀取一個布爾值
17         System.out.println(dis.readUTF());      //讀一個轉換成UTF-8編碼的字元串
18         dis.close ();                           //關閉流
19     }
20 }
View Code   只有讀取數據的順序與寫數據的順序保持一致,才能保證最終數據的正常性。 3、列印流PrintStream
 1 public class Example16 {
 2     public static void main(String[] args) throws Exception{
 3         PrintStream ps = new PrintStream(
 4                 new FileOutputStream("printStream.txt",true));
 5            Student stu = new Student();
 6            ps.print("這是一個數字");
 7            ps.println(19);
 8            ps.println(stu);
 9     }
10 }
11 class Student {
12     @Override
13     public String toString() {
14         return "我是一個學生";
15     }
16 }
View Code 4、標準輸入輸出流(in、out、err)
 1 public class Example17 {
 2     public static void main(String[] args) throws Exception{
 3         StringBuffer sb = new StringBuffer();
 4         int ch;
 5         //while迴圈用於讀取鍵盤輸入的數據
 6         while ((ch=System.in.read())!=-1){   //判斷是否讀取到數據的末尾
 7             //對輸入的字元進行判斷,如果是回車"\r"或者換行"\n",則跳出迴圈
 8             if(ch =='\r' || ch=='\n'){
 9                 break;
10             }
11             sb.append((char)ch);  //將讀取到的數據添加到sb中
12         }
13         System.out.println (sb);  //列印鍵盤輸入的數據
14     }
15 }
View Code  
重定向流常用的靜態方法
方法聲明 功能描述
void setIn(InputStream in) 對標準輸入流重定向
void setOut(PrintStream out) 對標準輸出流重定向
void setErr(PrintStream out) 對標準錯誤輸出流重定向
  5、管道流(PipedInputStream、PipedOutputStream)   多線程之間可以通過此管道流實現數據的傳輸。
 1 public class Example19 {
 2     public static void main(String[] args) throws Exception{
 3         final PipedInputStream  pis = new PipedInputStream();//創建PipedInputStream對象
 4         final PipedOutputStream pos = new PipedOutputStream();
 5         //PipedInputStream和PipedOutputStream建立連接,也可寫成pos.connect(pis)
 6         pis.connect(pos);
 7         new Thread(new Runnable(){          //創立線程
 8             public void run(){
 9                 //將從鍵盤讀取的數據寫入管道流中
10                 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
11                 //將從鍵盤讀取的數據寫入管道流中
12                 PrintStream ps = new PrintStream(pos);
13                 while (true){
14                    try{
15                       System.out.println(br.readLine());
16                       Thread.sleep(1000);
17                    }catch (Exception e){
18                         e.printStackTrace();
19                    }
20                 }
21             }
22         },"發送數據的線程").start();
23         new Thread(new Runnable() {
24             @Override
25             public void run() {
26                 //下麵代碼是從管道流中讀取數據,每讀一行數據輸出一次
27                 BufferedReader br = new BufferedReader(new InputStreamReader(pis));
28                 while (true){
29                     try{
30                         System.out.println(Thread.currentThread().getName()+"收到的內容:"+br.readLine());
31                     }catch (IOException e){
32                         e.printStackTrace();
33                     }
34                 }
35             }
36         },"接收數據的線程").start();
37     }
38 }
View Code 6、ByteArrayOutputStream、ByteArrayInputStream   將數據寫入(讀取)到緩衝區,最後一次性寫入(輸出)到文件。   如果讀取的文件非常大,就不能使用這個列,否則會造成記憶體溢出。
 1 public class Example20 {
 2     public static void main(String[] args) throws Exception{
 3         //將數據寫入緩衝區中
 4         FileInputStream fs = new FileInputStream("source.txt");
 5         //創建一個字接數據緩衝區
 6         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 7         FileOutputStream fos = new FileOutputStream("target1.txt");
 8         //下麵的代碼是迴圈讀取緩衝區中的數據,並將數據一次性寫入文件
 9         int b1;
10         while ((b1=fs.read())!=-1){
11             bos.write(b1);
12         }
13         fs.close();
14         bos.close();
15         fos.write(bos.toByteArray());//將緩衝區中的數據一次性寫入文件
16         fos.close();
17  
18         //讀取緩衝區中的數據
19         byte[] bufs = new byte[]{97,98,99,100};//創建一個位元組數組
20         ByteArrayInputStream bis = new ByteArrayInputStream(bufs);//讀取位元組數組中的數據
21         //下麵代碼是迴圈讀取緩衝區中的數據
22         int b2;
23         while ((b2=bis.read())!=-1){
24             System.out.println((char)b2);
25         }
26         bis.close();
27     }
28 }
View Code 7、CharArrayReader和CharArrayWriter   將字元型數據臨時存入緩衝區。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、對提交表單進行空值驗證 html代碼: js: 二、childNodes 和children 的區別 1、childNodes:它是標準屬性,它返回指定元素的子節點集合,包括HTML節點,所有屬性和文本節點(包括換行和空格也算一個節點)。 nodeType == 1時,表示該節點為元素節點, n ...
  • 1.maven是一個管理第三方庫的jar package 2.從該頁面下載相應的Maven jar包(http://maven.apache.org/download.cgi),linux OS下載尾碼為.tar.gz的壓縮包,windows OS下載尾碼為.zip的壓縮包。 3.下載完後,去相應的 ...
  • Matplotlib庫入門 Matplotlib庫介紹 Matliotlib庫是Python優秀的數據可視化第三方庫。 Matliotlib庫的效果見:http://matplotlib.org/gallery.html Matplotlib庫由各種可視化類構成,內部結構複雜,受Matlab啟發。 ...
  • 本文主要總結了java中this關鍵字的用法以及一些註意事項,對於大家遇到的各種問題可在文末留言筆者將盡全力幫助大家解答。 ...
  • 初步設計代碼如下: 使用判斷精靈頭腳與每個數組中圖片牆上下左右分別判斷 如精靈的右側與牆的左側判斷大小,同時判斷精靈的頭部是否被遮擋,精靈的腳部是否被遮擋 依次再判斷向左的情況,向上的情況,向下的情況 用簡單思路代替: 通過距離判定的方法 ...
  • 首先我們先來瞭解下瀏覽器的緩存 瀏覽器緩存機制 Cache-control策略 Cache-Control與Expires的作用一致,都是指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據還是重新發請求到伺服器取數據。只不過Cache-Control的選擇更多,設置更細緻,如果同時設置的話, ...
  • #include using namespace std; int main(){ int i,j; for(i=1;i<=60;i++){ for(j=1;j<=50;j++){ cout<<"*"; } cout<<endl; } } ...
  • 基礎數據類型包裝類 當一個程式要求互動式輸入一個int類型的年齡時,從文本框中輸入的結果肯定是String類型的。要在程式中進行相關操作,它必須先轉換為int類型。因此可以使用數據類型的轉換或強制轉換,但這種轉換方式太過簡單,功能太少,因此java中提供了數據類型包裝類的概念。 數據類型包裝類是指  ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...