- 編碼問題
- File類的使用
- RandomAccessFile
- 字節流
- 字符流
- 對象的序列化和反序列化
4-1 字節流之文件輸入流FileInputStrream-1
IO流(輸入流、輸出流)
字節流、字符流
1.字節流
1)InputStream、OputStream
- InputStream抽象了應用程序讀取數據的方式
- OutputStream抽象了應用程序寫出輸出的方式
2)EOF = End 讀到-1就讀到了結尾
3)輸入流基本方法
int b = in.read(); //讀取一個字節無符號填充到int的低8位,-1是 EOF
in.read(byte[] buf) ; //讀取數據填充到字節數組buf
in.read(byte[] buf, int start, int size); // 讀取數據到字節數組buf 從buf的start位置開始 存放size長度的數據
4)輸出流基本方法
out.write(int b); //寫出一個byte到流,b的低8位
out.write(byte[] buf); // 將bnf字節數組都寫入到流
out.write(byte[] buf,int start, int size); // 字節數組buf 從start位置開始 寫入size長度的字節流到流
5)FileInputStream--->具體實現了在文件上讀取數據
package com.io;
import java.io.FileInputStream;
import java.io.IOException;public class IOUtil {
/**
* 讀取指定文件內容,按照16進制輸出到控制檯 並且每輸出10個byte換行
*
* @param fileName
* @throws IOException
*/
public static void printHex(String fileName) throws IOException {
// 把文件做爲字節流進行讀操作
FileInputStream in = new FileInputStream(fileName);
int b;
int i = 1;
while ((b = in.read()) != -1) {
if (b < 0xf) {
// 單位數前面補0
System.out.print("0");
}
System.out.print(Integer.toHexString(b) + " "); // 將整型b轉換爲16進製表示的字符串
if (i++ % 10 == 0) {
System.out.println();
}
}
in.close();
}}
4-2 字節流之文件輸入流FileInputStrream-2
public static void printHexByByteArray(String fileName) throws IOException {
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[20 * 1024];
/*
* 從 in中批量讀取字節,放入到buf這個字節數組中, 從第0個位置開始放,最多放buf.length個 返回的是讀到字節的個數
*/
/*
* int bytes = in.read(buf,0,buf.length); //一次性讀完,說明字節數組足夠大 int j = 1; for (int
* i = 0; i < bytes; i++) { if (buf[i] <= 0xf) { System.out.print("0"); }
* System.out.print(Integer.toHexString(buf[i]) + " "); if (j++ %10 == 0) {
* System.out.println(); } }
*/
// 當字節數組不夠大,一次性讀不完時,怎麼辦
int bytes = 0;
int j = 1;
while ((bytes = in.read(buf, 0, buf.length)) != -1) {
for (int i = 0; i < buf.length; i++) {
// byte類型8位,int類型32位,爲了避免數據轉換錯誤,通過0xff將高24位清零
System.out.print(Integer.toHexString(buf[i] & 0xff) + " ");
if (j++ % 10 == 0) {
System.out.println();
}
}
}
}
4-3 字節流之文件輸出流FileOutputStream
FileOutputStream 實現了向文件中寫出byte數據的方法
package com.io;
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutDemo {
public static void main(String[] args) throws IOException {
// 如果該文件不存在,則直接創建;如果存在,刪除後創建
FileOutputStream out = new FileOutputStream("demo/out.dat");
// 要追加內容,第二個參數寫true,否則文件將被清空
out.write('A'); // 寫出了'A'的低8位
out.write('B'); // 寫出了'B'的第8位
int a = 10; // write 只能寫8位,那麼寫一個int需要寫4次每次8位
out.write(a >>> 24);
out.write(a >>> 16);
out.write(a >>> 8);
out.write(a);
byte[] gbk = "中國".getBytes("gbk");
out.write(gbk);
out.close();IOUtil.printHex("demo/out.dat");
}
}
文件複製
public static void copyFile(File srcFile, File destFile) throws IOException {
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件" + srcFile + "不存在");
}
if (!srcFile.isFile()) {
throw new IllegalArgumentException("文件" + srcFile + "不是文件");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[8 * 1024];
int b;
while ((b = in.read(buf, 0, buf.length)) != -1) {
out.write(buf, 0, b);
out.flush(); // 最好加上
}
in.close();
out.close();
}
4-4 字節流之數據輸入輸出流
DataOutputStream/DateOutputStream
對“流”的功能的擴展,可以更加方便的讀取int,long,字符等類型的數據
DateOutputStream
writeInt()/wirteDouble()/writeUTF()
package com.io;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class DosDemo {
public static void main(String[] args) throws IOException {
String file = "demo/dos.dat";
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
dos.writeInt(10);
dos.writeInt(-10);
dos.writeLong(10l);
dos.writeDouble(10.5);
// 採用utf-8編碼寫出
dos.writeUTF("中國");
// 採用utf-16be編碼寫出
dos.writeChars("中國");
dos.close();
IOUtil.printHex(file);
}}
package com.io;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;public class DisDemo {
public static void main(String[] args) throws IOException {
String file = "demo/dos.dat";
IOUtil.printHex(file);
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int i = dis.readInt();
System.out.println(i);
i = dis.readInt();
System.out.println(i);
long l = dis.readLong();
System.out.println(l);
double b = dis.readDouble();
System.out.println(b);
String s = dis.readUTF();
System.out.println(s);
dis.close();
}}
4-5 字節流緩衝
BufferedInputStream & BufferedOutputStream
這兩個流類爲IO提供了帶緩衝區的操作,一般打開文件運行寫入或讀取操作時,都會加上緩衝,這種流模式提高了IO的性能
從應用程序中把數據放入文件,就相當於將一缸水導入到另一個缸中:
FileOutputStream--->wirte()方法相當於一滴一滴地把水“轉移”過去
DataOutputStream--->wirteXXX()方法會方便一些,相當於一瓢一瓢把水“”轉移“”
BufferedOutputStream--->wirte()方法更方便,相當於一瓢一瓢水先放入桶中,再從桶中倒入另一個缸中
/**
* 進行文件的拷貝,利用帶緩衝的字節流
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFileByBuffer(File srcFile, File destFile) throws IOException{
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件" + srcFile + "不存在");
}
if (!srcFile.isFile()) {
throw new IllegalArgumentException("文件" + srcFile + "不是文件");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
int c;
while ((c = bis.read()) != -1) {
bos.write(c);
bos.flush(); // 刷新緩衝區
}
bis.close();
bos.close();
}