文件编码和RandomAccessFile文件流的使用--IO学习笔记(一)
文件編碼
UTF-8編碼:中文占用3個字節,英文占用1個字節
GBK編碼:中文占用2個字節,英文占用1個字節
UTF-16BE編碼:中文占用2個字節,英文占用兩個字節
注意:其中UTF-16BE編碼是java的雙字節編碼采用的編碼方式。Java里使用的是UTF-16BE 方式來存儲數據的。eg:String 字符串就是采用UTF-16BE編碼。
package com.test.test;/*** 使用三種編碼方式打印同一個字符串,查看每種編碼方式所占用字節多少的區別**/ public class Test {public static void main(String[] args) throws Exception{String s = "小灰灰ABC";encodeGBK(s);encodeUTF8(s);encodeUTF16BE(s);}/*** 使用GBK編碼方式* @param s*/private static void encodeGBK(String s) {System.out.println("GBK編碼:");// 將字符串轉換成字節數組(默認采用的是項目設置的編碼格式(我這里設置的是GBK)的轉換的編碼格式)byte[] byte1 = s.getBytes();for (byte b : byte1) {/** 1.toHexString()方法,把字節轉換成了int類型并且以16進制的方式顯示* 2.方法中把byte(字節)轉換成了int類型* 3.&0xff的意思是只取最低的后8位:因為int類型占32位(4個字節)但是byte類型是占用8位(1個字節),* 所以將byte轉換成int后,int類型前面的24位就會是0,所以可以使用&0xff只取后8位*/System.out.print(Integer.toHexString(b & 0xff) + " ");}System.out.println();}/*** 使用UTF-8編碼方式* @param s*/private static void encodeUTF8(String s) throws Exception{System.out.println("UTF8編碼:");// 將字符串轉換成字節數組(默認采用的是項目設置的編碼格式(我這里設置的是GBK)的轉換的編碼格式)byte[] byte1 = s.getBytes("utf-8");for (byte b : byte1) {System.out.print(Integer.toHexString(b & 0xff) + " ");}System.out.println();}/*** 使用UTF-16BE編碼方式* @param s*/private static void encodeUTF16BE(String s) throws Exception{System.out.println("UTF16BE編碼:");// 將字符串轉換成字節數組(默認采用的是項目設置的編碼格式(我這里設置的是GBK)的轉換的編碼格式)byte[] byte1 = s.getBytes("utf-16be");for (byte b : byte1) {System.out.print(Integer.toHexString(b & 0xff) + " ");}System.out.println();}}結果截圖:
從圖中可以看出這三種編碼方式的中英文所占用的字節數的差別。
注意:當你的字節序列是某種編碼時,這個時候想把字節序列變成字符串,也需要用這種編碼方式,否則會出現亂碼。
eg:
結果截圖:
這里可以知道如果想要出現原來的結果就必須采用原來的編碼方式轉換。
所以上邊的構造字符串的代碼應該修改為:
String str = new String(bytes,“utf-8”);
就會出現正確的結果:
RandomAccessFile文件流:
java文件的模型:
在硬盤上的文件是byte byte byte存儲的,是數據的集合。
1.介紹:
(1)RandomAccessFile是java提供的對文件內容的訪問類,既可以讀文件,也可以寫文件。
(2)支持隨機訪問文件,可以訪問文件的任意位置
2.打開文件
有兩種方式:“rw”(讀寫)和“r”(只讀)
eg:
RandomAccessFile raf = new RandomAccessFile(file,”rw”);
3.文件指針
這里的文件指針就是RandomAccessFile可以訪問文件任意位置的基礎。
打開文件的時候指針在開頭,pointer = 0;
獲取文件指針的方法:raf.getFilePointer();
4.寫方法
raf.write();
只能寫一個字節(也就是只寫最后的8位),寫完之后指針會自動指向下一個位置,準備再次寫入。
5.讀文件
int i = raf.read();
從指針所在的位置讀一個字節,同時將這個字節轉換成為int類型,就是說都出一個字節,填充到int的最后8位。
read();只能讀取一個字節。
read(byte[]);就可以讀到一個字節數組里邊
6.關閉流
raf.close();
文件讀寫完成后一定要關閉流
下面是RandomAccessFile類的基本的使用方法的例子:
package com.test.random;import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.Arrays;public class RandomAccessFileTest {public static void main(String[] args) throws IOException {File dir = new File("demo");// 如果沒有寫絕對路徑,那么默認就是在項目中創建該文件if (!dir.exists()) {dir.mkdir();//創建目錄文件}File file = new File(dir, "test.txt");if (!file.exists()) {file.createNewFile();//創建文件}RandomAccessFile raf = new RandomAccessFile(file, "rw");//設置可讀,可寫操作System.out.println("指針的位置:"+raf.getFilePointer());//指針的位置//寫一個字節(后8位)進去(這里寫入的內容是char類型的,其實char類型所占就是8位(1個字節),所以這里可以完整的寫入一個A)raf.write('A');System.out.println("指針的位置:"+raf.getFilePointer());//指針的位置raf.write('B');System.out.println("已經寫入的長度:"+raf.length());//寫入的長度//用write()方法,寫一個int類型的值(int是4個字節(32位))int i = 1;raf.write(i>>>24&0xff);//寫int的最高8位(24-32之間的8位)raf.write(i>>>16&0xff);//寫int的(16-24之間的8位)raf.write(i>>>8&0xff);//寫int的(8-16之間的8位)raf.write(i&0xff);//寫int的后8位(0-8之間的8位)//用writeInt()方法(RandomAccessFile自帶的寫int類型的方法),寫一個int類型的值int j = 1;raf.writeInt(j);//其實writeInt()方法內部就是通過上邊的方法實現的寫int類型的值System.out.println("指針的位置:"+raf.getFilePointer());System.out.println("已經寫入的長度:"+raf.length());//寫一個String類型的值String s = "我";//中文是2個字節(16位)byte[] bytes = s.getBytes();//將String類型轉換成字節數組(byte類型的),byte占用1個字節(8位)raf.write(bytes);//write()方法可以寫一個字節數組//如果想從頭開始讀取文件內容,就必須把指針移到文件頭部raf.seek(0);//把指針移到文件的頭部//一次性讀取,把文件的內容都讀到字節數組中去byte[] buf = new byte[(int)raf.length()];raf.read(buf);System.out.println(Arrays.toString(buf));//封裝成字符串String str = new String(buf);System.out.println(str);//以16進制的方式輸出for (byte b : buf) {System.out.println(Integer.toHexString(b&0xff)+" ");}raf.close();}}結果截圖:
總結
以上是生活随笔為你收集整理的文件编码和RandomAccessFile文件流的使用--IO学习笔记(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Runnable和Thread基础---
- 下一篇: 字节流--IO学习笔记(二)