日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

五.Java IO、NIO、文件、通讯

發(fā)布時間:2025/5/22 java 142 豆豆
生活随笔 收集整理的這篇文章主要介紹了 五.Java IO、NIO、文件、通讯 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

Java 的 I/O 大概可以分成四組:
基于字節(jié)操作的 I/O :InputStream 和 OutputStream
基于字符操作的 I/O :Writer 和 Reader
基于磁盤操作的 I/O :File
基于網(wǎng)絡(luò)操作的 I/O :Socket


輸入流只能讀不能寫.
輸出流只能寫不能讀.
!java.io.RandomAccessFile類是可讀可寫的。


5.1 IO

InputStream/OutputStream的工作原理:
InputStream/OutputStream( 字節(jié)流 ) :一次傳送一個字節(jié)。
IO中以byte[]作為緩沖,從源(可以是文件,內(nèi)存中的數(shù)據(jù)等等)中讀取數(shù)據(jù)到byte[]中,寫入數(shù)據(jù)的時候,將byte[]寫入到目標(biāo)。
InputStream類中的read(byte b[], int off, int len)方法(部分):

[java]?view plaincopy

  • int?i?=?1;??

  • ?for?(;?i?<?len?;?i++)?{??

  • ?????c?=?read();??

  • ?????if?(c?==?-1)?{??

  • ?????????break;??

  • ?????}??

  • ?????b[off?+?i]?=?(byte)c;??

  • ?}??



  • 每次從源中讀取一個字節(jié),存儲到byte[] b中。最多讀取len個字節(jié)。緩沖區(qū)讀滿或者到達(dá)源末尾后,將緩沖區(qū)的數(shù)據(jù)寫入目標(biāo)。
    read()是一個native方法,正常返回0-255,到達(dá)源數(shù)據(jù)的末尾返回-1
    InputStream/OutputStream是抽象類,使用的是其子類,子類會重新定義相關(guān)方法。為了性能這些子類中的底層實現(xiàn)都是native方法。


    Writer/Reader實現(xiàn)原理相似,不同的是將流數(shù)據(jù)以一個字符的長度為單位處理,并進(jìn)行編碼轉(zhuǎn)換。


    5.2 NIO



    NIO特性之一:為所有的原始類型提供(Buffer)緩存支持
    拷貝文件測試IO和NIO的讀寫速度:

    [java]?view plaincopy

  • //IO方式??

  • public??void?copyFileByIO(File?file,?File?newFile)??

  • {??

  • ????try??

  • ????{??

  • ????????FileInputStream?fis?=?new?FileInputStream(file);??

  • ????????FileOutputStream?fos?=?new?FileOutputStream(newFile,?true);??

  • ????????byte[]?bytes?=?new?byte[1024];??

  • ????????while?(fis.read(bytes)?!=?-1)??

  • ????????{??

  • ????????????fos.write(bytes);??

  • ????????}??

  • ????????if(fis!=null)??

  • ????????????fis.close();??

  • ????????if(fos!=null)??

  • ????????????fos.close();??

  • ????}??

  • ????catch?(IOException?e)??

  • ????{??

  • ????????e.printStackTrace();??

  • ????}??

  • }??

  • //NIO方式??

  • public?static?void?copyFileByNIO(File?file,?File?newFile)??

  • {??

  • ????try??

  • ????{??

  • ????????FileChannel?fcin?=?new?FileInputStream(file).getChannel();??

  • ????????FileChannel?fcout?=?new?FileOutputStream(newFile,?true).getChannel();??

  • ????????ByteBuffer?bb?=?ByteBuffer.allocate(1024);??

  • ????????while?(fcin.read(bb)?!=?-1)??

  • ????????{??

  • ????????????bb.flip();??

  • ????????????fcout.write(bb);??

  • ????????????bb.clear();??

  • ????????}??

  • ????????if(fcin!=null)??

  • ????????????fcin.close();??

  • ????????if(fcout!=null)??

  • ????????????fcout.close();??

  • ????}??

  • ????catch?(IOException?e)??

  • ????{??

  • ????????e.printStackTrace();??

  • ????}??

  • }??





  • 文件大小:3.2G
    >> IO 讀寫耗時:114320 速度:30.45 M/s
    >> NIO 讀寫耗時:86009 速度:40.47 M/s


    NIO中使用Buffer來作為讀寫中轉(zhuǎn),Buffer是一個連續(xù)的內(nèi)存塊。
    IO以流的方式處理數(shù)據(jù),NIO以塊的方式處理數(shù)據(jù)。
    NIO中通過channel操作Buffer緩沖區(qū),所以NIO速度比IO要快很多。


    5.3 文件

    文件處理是Java IO系統(tǒng)中的一個子系統(tǒng)。
    比如要讀取文件,只需要new一個FileInputStream,即可以流的方式讀取文件。
    ?public FileInputStream(String name)
    ?public FileInputStream(File file)
    這兩種方式都可以從文件創(chuàng)建一個輸入流。
    和其它的一樣read()方法都是native的,FileInputStream命名是以InputStream結(jié)尾說明他是一個輸入流,那么它的工作原理就和其它流一樣。
    FileInputStream中有一個getChannel(),可以得到一個FileChannel對象。這是NIO中的特性,通過channel讀/寫數(shù)據(jù),提高了性能。


    File類:


    public String getName() {
    ? ? ? int index = path.lastIndexOf(separatorChar);
    ? ? ? if (index < prefixLength) return path.substring(prefixLength);
    ? ? ? return path.substring(index + 1);
    ? }
    得到文件名,其實是獲得完整路徑中的最后一個/(separatorChar根據(jù)系統(tǒng)匹配/或者\),然后截取到文件名。
    同樣的getParent()也是通過截取字符串來獲得父目錄。
    File類包含了許多對文件的操作:
    ?public boolean isFile()?//判斷是不是一個文件
    ?public boolean isHidden()?//判斷是不是隱藏
    ?public long length()?//文件長度
    ?public boolean exists()?//文件或目錄是否存在
    ?public boolean createNewFile() //創(chuàng)建文件
    ?public boolean delete()?//刪除文件
    ?...
    但是,File類并不只是指文件,可以將其表示為目錄。
    File file=new File( "D:/");
    同樣的File類中也包含了對目錄的操作:
    ?public boolean isDirectory() //判斷是不是一個文件夾
    ?public String[] list()?//得到文件夾下的文件和目錄的名字
    ?public File[] listFiles()?//得到文件夾下的文件
    ?public boolean mkdir()?//創(chuàng)建目錄
    ?public boolean renameTo?//重命名
    ?...


    示例:
    File file=new File("c:/");
    String[] files = file.list();
    for(String s:files)
    {
    System.out.println(s);
    }
    輸出:
    $RECYCLE.BIN
    alipay
    bcd.dna.LOG1
    bcd.dna.LOG2
    Boot
    bootmgr
    BOOTSECT.BAK
    cygwin
    Documents and Settings
    maxldr.mbr
    Program Files
    Program Files (x86)
    ProgramData
    Recovery
    RECYCLER
    System Volume Information
    TCKYU
    Users
    Windows


    可以看到list()將所有文件和文件夾都列了出來,包括隱藏文件和文件夾,順序和實際文件夾中的顯示順序一致。




    5.4 通訊



    NIO特性之二:異步 I/O 支持
    在通訊中就是: 提供多路 (non-bloking) 非阻塞式的高伸縮性網(wǎng)絡(luò) I/O?


    阻塞式網(wǎng)絡(luò)IO:

    [java]?view plaincopy

  • ServerSocket?server=new?ServerSocket(9999);???

  • ?Socket?socket=server.accept();//使用accept()阻塞等待請求??

  • ?BufferedReader?is=new?BufferedReader(new?InputStreamReader(client.getInputStream()));????

  • ?PrintWriter?os=new?PrintWriter(client.getOutputStream());????

  • ?BufferedReader?sin=new?BufferedReader(new?InputStreamReader(System.in));????

  • ?while(true)??

  • ?{????

  • ????String?str=is.readLine();??

  • ?}??

  • ?//...??



  • accept()如果沒有連接會一直阻塞
    readLine()如果沒有讀取到數(shù)據(jù),也會一直阻塞。
    這樣的方式,每個和客戶端的連接都要用一個單獨的線程來處理,每個線程擁有自己的棧空間并且占用一些 CPU 時間,當(dāng)沒有請求的時候就會阻塞。
    假如每個客戶端一天之和服務(wù)器通訊一次,那么這些線程全部都必須存在一天。這樣就會浪費系統(tǒng)資源。


    非阻塞式網(wǎng)絡(luò)IO:
    由一個專門的線程來處理所有的 IO 事件,并負(fù)責(zé)分發(fā),采用事件驅(qū)動機制,事件到的時候才觸發(fā)。


    5.5 關(guān)于TCP、UDP、HTTP

    TCP/IP是個協(xié)議組,可分為三個層次:
    網(wǎng)絡(luò)層:IP協(xié)議、ICMP協(xié)議、ARP協(xié)議、RARP協(xié)議和BOOTP協(xié)議。
    傳輸層:TCP協(xié)議、UDP協(xié)議。
    應(yīng)用層:FTP、HTTP、TELNET、SMTP、DNS等協(xié)議


    !socket只是一種連接模式,不是協(xié)議。


    TCP是基于連接的協(xié)議,必須建立好了連接,才能通訊。
    適合傳輸大量數(shù)據(jù),可靠的連接。
    UDP不需要建立連接,直接把數(shù)據(jù)發(fā)送過去。因為不需要連接,所以效率高,但是可靠性沒有TCP高。
    適合速度快的,數(shù)據(jù)少的。


    !ping命令的實現(xiàn)就是基于UDP。


    http是一個協(xié)議,但是底層還是基于tcp的,
    HTTP協(xié)議是建立在請求/響應(yīng)模型上的。客戶建立給服務(wù)器發(fā)送一條請求,服務(wù)器收到請求,給客戶端返回一個響應(yīng)。


    轉(zhuǎn)載于:https://my.oschina.net/bv10000/blog/187589

    總結(jié)

    以上是生活随笔為你收集整理的五.Java IO、NIO、文件、通讯的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。