復習
我們用下面一段代碼來復習一下昨天學的內容
File dir = new File("E:\\Workspace\\IdeaStudio\\io-demo\\random-access-file\\demo");
if (!dir.exists()) {
dir.mkdir();
}
if (!dir.isDirectory()) {
System.out.println("新建目錄出錯");
}
File file = new File(dir, "file.dat");
if (!file.exists()) {
boolean rs1 = file.createNewFile();
if (!rs1) {
System.out.println("創(chuàng)建文件失敗");
}
}
if (!file.isFile()) {
System.out.println("新建文件出錯");
}
我們從構成方法開始
API
RandomAccessFile(File file, String mode)
創(chuàng)建一個隨機訪問文件流從File參數(shù)指定的文件中讀取,并可選地寫入文件。
RandomAccessFile(String name, String mode)
創(chuàng)建隨機訪問文件流,以從中指定名稱的文件讀取,并可選擇寫入文件。
我們關心一下這個參數(shù) mode:
Value Meaning "r" Open for reading only. Invoking any of the write methods of the resulting object will cause an IOException to be thrown. "rw" Open for reading and writing. If the file does not already exist then an attempt will be made to create it. "rws" Open for reading and writing, as with "rw", and also require that every update to the file's content or metadata be written synchronously to the underlying storage device. "rwd" Open for reading and writing, as with "rw", and also require that every update to the file's content be written synchronously to the underlying storage device.
大概是說有四種模式:"r"(只讀)、"rw"(讀寫)、"rwd"、"rws"。
于是:
String mode = "rw";
RandomAccessFile randomAccessFile = new RandomAccessFile(file, mode);
寫點東西
API
void write(int b)
將指定的字節(jié)寫入此文件。
詳細看一下:
public void write(int b)
throws IOException將指定的字節(jié)寫入此文件。 寫入從當前文件指針開始。
Specified by:
write在界面 DataOutput
參數(shù)
b - byte 。
異常
IOException - 如果發(fā)生I / O錯誤。
這里最重要的亮點:
1、參數(shù):寫進去一次一個字節(jié)(bye 8位)
2、指針
那怎么樣把一個整數(shù)寫進去呢?
int b = 0x7fffffff;
randomAccessFile.write(b >>> 24);
randomAccessFile.write(b >>> 16);
randomAccessFile.write(b >>> 8);
randomAccessFile.write(b);
System.out.println(randomAccessFile.getFilePointer());
測試結果:
0
4
Process finished with exit code 0
讀一下
API
int read()
從該文件讀取一個字節(jié)的數(shù)據(jù)。
int read(byte[] b)
從該文件讀取最多 b.length字節(jié)的數(shù)據(jù)到字節(jié)數(shù)組。
byte[] c = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(c);
System.out.println(Arrays.toString(c));
項目經(jīng)驗
之前在寫一個物聯(lián)網(wǎng)網(wǎng)關短信平臺的時候,數(shù)據(jù)傳輸就用到byte,那時候就需要對這一塊熟悉,還好,網(wǎng)上參考資料比較多,復制粘貼下來,也能解決。我們來看一下:
public final void writeInt(int v) throws IOException {
write((v >>> 24) & 0xFF);
write((v >>> 16) & 0xFF);
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
//written += 4;
}
public final void writeLong(long v) throws IOException {
write((int)(v >>> 56) & 0xFF);
write((int)(v >>> 48) & 0xFF);
write((int)(v >>> 40) & 0xFF);
write((int)(v >>> 32) & 0xFF);
write((int)(v >>> 24) & 0xFF);
write((int)(v >>> 16) & 0xFF);
write((int)(v >>> 8) & 0xFF);
write((int)(v >>> 0) & 0xFF);
//written += 8;
}
public final void writeChars(String s) throws IOException {
int clen = s.length();
int blen = 2*clen;
byte[] b = new byte[blen];
char[] c = new char[clen];
s.getChars(0, clen, c, 0);
for (int i = 0, j = 0; i < clen; i++) {
b[j++] = (byte)(c[i] >>> 8);
b[j++] = (byte)(c[i] >>> 0);
}
writeBytes(b, 0, blen);
}
如果你在寫項目的時候,有去看過大佬封裝的Util,以上這些代碼很眼熟吧,當然這些也是jdk大神提供給我們的。
編碼
短信傳輸?shù)木幋a是 UCS2 ,這對中文來說無疑是要亂碼的,那怎么辦呢?
如果你也遇到這個問題,我相信你是痛苦的。
當時搜索了大量資料,請教了很多人,當然也有代碼。解決方案是:直接轉成 UTF-16BE。
這是什么編碼,聽都沒聽過。
Java是雙字節(jié)編碼,就是UTF-16BE。
String s2 = "中";
randomAccessFile.writeChars(s2);
System.out.println(randomAccessFile.getFilePointer());
randomAccessFile.seek(0);
// 寫進去了嗎,讀一下
byte[] c = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(c);
System.out.println(Arrays.toString(c));
String s1 = new String(c, "utf-16be");
System.out.println(s1);
randomAccessFile.close();
0
2
[78, 45]
中
Process finished with exit code 0
另外,文件都是byte。
資料
1、本節(jié)測試代碼:random-access-file