Java IO學習筆記二
流的概念
- 在程序中所有的數(shù)據都是以流的方式進行傳輸或保存的匹表,程序需要數(shù)據的時候要使用輸入流讀取數(shù)據捕儒,而當程序需要將一些數(shù)據保存起來的時候蒲犬,就要使用輸出流完成届案。
- 程序中的輸入輸出都是以流的形式保存的臭埋,流中保存的實際上全都是字節(jié)文件弱睦。
字節(jié)流和字符流
- 實際上字節(jié)流在操作時本身不會用到緩沖區(qū)(內存)百姓,是文件本身直接操作的,而字符流在操作時使用了緩沖區(qū)况木,通過緩沖區(qū)再操作文件
- 在java.io包中操作文件內容的主要有兩大類:字節(jié)流垒拢、字符流,兩類都分為輸入和輸出操作火惊。在字節(jié)流中輸出數(shù)據主要是使用OutputStream完成求类,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成屹耐,輸入流主要使用Reader類完成尸疆。(這四個都是抽象類)
操作流程
在Java中IO操作也是有相應步驟的,以文件操作為例,主要的操作流程如下:
- 使用
File
類打開一個文件- 通過字節(jié)流或字符流的子類寿弱,指定輸出的位置
- 進行讀/寫操作
- 關閉輸入/輸出
字節(jié)流
字節(jié)流主要是操作byte類型數(shù)據犯眠,以byte數(shù)組為準,主要操作類就是
OutputStream
症革、InputStream
FileOutputStream
- 文件輸出流是用于將數(shù)據寫入 File 或 FileDescriptor 的輸出流筐咧。文件是否可用或能否可以被創(chuàng)建取決于基礎平臺。特別是某些平臺一次只允許一個 FileOutputStream(或其他文件寫入對象)打開文件進行寫入噪矛。在這種情況下量蕊,如果所涉及的文件已經打開,則此類中的構造方法將失敗摩疑。
- FileOutputStream 用于寫入諸如圖像數(shù)據之類的原始字節(jié)的流危融。要寫入字符流,請考慮使用 FileWriter雷袋。
- 主要的功能就是用來向文件中寫入內容的
構造函數(shù)
FileOutputStream(File file)
創(chuàng)建一個向指定 File 對象表示的文件中寫入數(shù)據的文件輸出流。FileOutputStream(File file, boolean append)
如果在文件后面追加內容辞居,如果append為true則追加內容FileOutputStream(String name)
創(chuàng)建一個向具有指定名稱的文件中寫入數(shù)據的輸出文件流楷怒。FileOutputStream(String name, boolean append)
創(chuàng)建一個向具有指定 name 的文件中寫入數(shù)據的輸出文件流。
常用的方法
close()
關閉文件輸出流void write(byte[] b)
將 b.length 個字節(jié)從指定 byte 數(shù)組寫入此文件輸出流中瓦灶。void write(byte[] b, int off, int len)
將指定 byte 數(shù)組中從偏移量 off 開始的 len 個字節(jié)寫入此文件輸出流鸠删,這里需要注意的是中文所占字節(jié)數(shù)為3,英文所占字節(jié)數(shù)為1void write(int b)
將指定字節(jié)寫入此文件輸出流贼陶,這個是按照ascii碼寫入文件的刃泡,并不是直接寫入的是整數(shù)
實例
package File_demo;
import java.io.*;
public class demo {
public static void main(String[] args) {
FileOutputStream outputStream = null;
File file = new File("/tmp" + File.separator + "test.txt");
try {
outputStream = new FileOutputStream(file);
try {
int data = 48;
String name = "陳加兵\n"; //使用\n換行
byte[] bytes = name.getBytes(); //將字符串轉換成byte數(shù)組
outputStream.write(bytes, 0, 3); //將中文字符串的第一個字寫入,這里一個中文占了三個字節(jié)
String age = "chenjiabing\n";
outputStream.write(age.getBytes());
outputStream.write(data); //這里的寫入的acsii碼中的(
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close(); //關閉文件流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
當然也可以一個一個的字節(jié)輸出
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Test11 {
public static void main(String[] args) throws IOException {
File f = new File("d:" + File.separator+"test.txt");
OutputStream out=new FileOutputStream(f);//如果文件不存在會自動創(chuàng)建
String str="Hello World";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]);
}
out.close();
}
}
FileInputStream
FileInputStream
從文件系統(tǒng)中的某個文件中獲得輸入字節(jié)碉怔。哪些文件可用取決于主機環(huán)境烘贴。FileInputStream
用于讀取諸如圖像數(shù)據之類的原始字節(jié)流。要讀取字符流撮胧,請考慮使用 FileReader桨踪。- 主要的功能是讀取文件中的內容
構造函數(shù)
FileInputStream(File file)
通過打開一個到實際文件的連接來創(chuàng)建一個 FileInputStream,該文件通過文件系統(tǒng)中的File對file指定芹啥。FileInputStream(String name)
通過打開一個到實際文件的連接來創(chuàng)建一個 FileInputStream锻离,該文件通過文件系統(tǒng)中的路徑名 name 指定。
常用方法
int read()
從輸入流中讀取數(shù)據字節(jié)墓怀,如果到達文件的末尾就返回-1int read(byte[] b)
將文件中的內容讀取到byte數(shù)組中汽纠,如果到達文件末尾返回-1int read(byte[] b, int off, int len)
從此輸入流中將最多 len 個字節(jié)的數(shù)據讀入一個 byte 數(shù)組中,這個用于截取字節(jié)流,注意這里中文是占三個字節(jié)long skip(long n)
從輸入流中跳過并丟棄 n 個字節(jié)的數(shù)據傀履,一旦跳過字節(jié)那么就從跳過的字節(jié)的后面開始讀取int available()
返回的數(shù)據是輸入流中的字節(jié)數(shù)虱朵,如果沒有字節(jié)就返回0,因此可以用這個函數(shù)判斷文件中是否還有內容
實例
- 針對知道的文件的大小然后創(chuàng)建一個數(shù)組存儲,之后將數(shù)組轉換成字符串卧秘,當然我們也可以一個一個的讀取
File file=new File("/tmp"+File.separator+"test.txt");
FileInputStream inputStream=null;
try {
inputStream=new FileInputStream(file);
try {
byte[] bytes=new byte[(int)file.length()]; //file.length返回文件的大小呢袱,這樣就不會浪內存空間了
int flag=inputStream.read(bytes); //將文件的內容讀入到數(shù)組中
System.out.println(new String(bytes)); //將bytes數(shù)組轉換成字符串輸出
System.out.println(flag);
}catch (IOException e)
{
e.printStackTrace();
}
}catch (FileNotFoundException e)
{
e.printStackTrace();
}finally {
if(inputStream!=null)
{
try {
inputStream.close();
}catch (IOException e)
{
e.printStackTrace();
}
}
}
- 一個一個的讀文件
File file=new File("/tmp"+File.separator+"test.txt");
FileInputStream inputStream=null;
try {
inputStream=new FileInputStream(file);
try {
int len=0; //讀取的字節(jié)
int i=0; //下標
byte[] bytes=new byte[(int)file.length()]; //創(chuàng)建數(shù)組
while((len=inputStream.read())!=-1) //判斷是否讀取到文件的末尾
{
bytes[i]=(byte)len; //將讀到的整形數(shù)據轉換成bytes類型的,存儲在數(shù)組中
i++;
}
System.out.println(new String(bytes)); //轉換成字符串
}catch (IOException e)
{
e.printStackTrace();
}
}catch (FileNotFoundException e)
{
e.printStackTrace();
}finally {
if(inputStream!=null)
{
try {
inputStream.close();
}catch (IOException e)
{
e.printStackTrace();
}
}
}
- 使用available控制結束
File file = new File("/tmp" + File.separator + "test.txt");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
try {
byte[] bytes = new byte[(int) file.length()]; //file.length返回文件的大小翅敌,這樣就不會浪內存空間了
int i = 0;
while (inputStream.available() != 0) {
try {
bytes[i] = (byte) inputStream.read();
i++;
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(new String(bytes));
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流
- 在程序中一個字符等于兩個字節(jié)羞福,那么java提供了Reader、Writer兩個專門操作字符流的類蚯涮。
- 前面已經說過字符流要用到緩沖區(qū)治专,因此在關閉字符流的時候一定要刷新緩沖區(qū),清空緩沖區(qū)中的內容
字符輸出流
FileWriter
- 用來寫入字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節(jié)緩沖區(qū)大小都是可接受的遭顶。
FileWriter
用于寫入字符流张峰。要寫入原始字節(jié)流,請考慮使用FileOutputStream
棒旗。- 主要功能是向文件中寫入內容
構造函數(shù)
FileWriter(File file)
根據給定的 File 對象構造一個 FileWriter 對象喘批。FileWriter(File file,boolean append)
追加FileWriter(String fileName)
根據給定的文件名構造一個 FileWriter 對象。FileWriter(String fileName, boolean append)
根據給定的文件名以及指示是否附加寫入數(shù)據的 boolean 值來構造 FileWriter 對象铣揉。
常用方法
write(String str)
將字符寫入文件write(String str,int offest,int len)
截取字符串部分內容寫入文件write(int c)
寫入單個字符饶深,并不是整數(shù)close()
關閉流,在關閉之前必須刷新緩沖區(qū)flush()
刷新緩沖區(qū)
實例
File file=new File("/tmp"+File.separator+"test"+File.separator+"test.txt");
File f1=new File("/tmp"+File.separator+"test");
if(!f1.exists())
{
f1.mkdir();
System.out.println("文件創(chuàng)建成功");
}
FileWriter fileWriter=null;
try {
fileWriter=new FileWriter(file);
String str="hello chenjiabing\n";
String name="陳加兵";
int data=48;
fileWriter.write(str); //寫入字符串
fileWriter.write(name); //寫入中文字符串逛拱,這里直接寫入不用轉換成byte數(shù)組了
fileWriter.write(data); //寫入單個字符
}catch (IOException e)
{
e.printStackTrace();
}finally {
if(fileWriter!=null)
{
try {
fileWriter.flush(); //刷新緩沖區(qū)
fileWriter.close(); //關閉字符流
}catch (IOException e)
{
e.printStackTrace();
}
}
}
注意: 這里字符流如果不關閉的話敌厘,那么就會就會寫入文件失敗,文件中沒有內容朽合,但是如果只有flush而沒有close文件還是會寫入成功的
字符輸入流
FileReader
- 用來讀取字符文件的便捷類俱两。此類的構造方法假定默認字符編碼和默認字節(jié)緩沖區(qū)大小都是適當?shù)?/li>
- 主要的功能是讀取文件內容
構造函數(shù)
FileReader(File file)
在給定從中讀取數(shù)據的 File 的情況下創(chuàng)建一個新FileReader
。FileReader(String fileName)
在給定從中讀取數(shù)據的文件名的情況下創(chuàng)建一個新FileReader
曹步。
常用函數(shù)
int read(char[] cbuf)
將字符讀入數(shù)組宪彩。int read()
讀取單個字符,之后使用char類型強制轉換成字符就行read(char[] cbuf, int off, int len)
將字符讀入數(shù)組的某一部分箭窜。boolean ready()
判斷是否準備讀取此流毯焕,如果讀到文件末尾那么就返回falselong skip(long n)
跳過字符。
實例
- 用字符數(shù)組讀取
File file = new File("/tmp" + File.separator + "test" + File.separator + "test.txt");
FileReader fileReader = null;
try {
fileReader = new FileReader(file);
char[] c = new char[(int) file.length()]; //根據文件的大小申請數(shù)組大小磺樱,不浪費
try {
int len = fileReader.read(c); //將文件的內容讀取到字符數(shù)組中
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]); //將一個一個字符輸出
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 使用
ready
控制是否讀到文件末尾纳猫,當然也可以使用int read()==-1
判斷
File file = new File("/tmp" + File.separator + "test" + File.separator + "test.txt");
FileReader fileReader = null;
try {
fileReader = new FileReader(file);
char[] c = new char[(int) file.length()]; //根據文件的大小申請數(shù)組大小,不浪費
try {
while(fileReader.ready()) //判斷是否讀到文件末尾
{
System.out.println((char)fileReader.read()); //轉換成字符
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}