檔案


常見的檔案操作

方式一
public static void main(String[] args) {
File newFile2 = new File("d:\\news2.txt"); //一個 \ 為轉義字符
try {
newFile2.createNewFile(); //會拋出一個例外 ,回傳值是一個布林值
System.out.println("檔案創建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
注意這里的File物件,只是一個物件,只有在執行createNewFile方法,才會真正創建檔案,
方式二
public static void main(String[] args) {
File newFile1 = new File("d:\\","news2.txt"); //注意不能寫成d,可以寫成d:/
try {
newFile1.createNewFile(); //會拋出一個例外
System.out.println("檔案創建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
方式三(不常用)
public static void main(String[] args) {
File file = new File("d:\\");
File newFile3 = new File(file,"news3.txt");
try {
newFile3.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
其它常用方法
public static void main(String[] args) {
File file = new File("d:\\news1.txt");
System.out.println(file.getName()); //獲取檔案名 news1.txt
System.out.println(file.getParent()); //檔案父級目錄 d:\
System.out.println(file.length()); // 檔案大小(位元組)
System.out.println(file.exists()); // 檔案是否存在 (因為上面已經創建所以為T)
System.out.println(file.isFile()); // 是不是一個檔案 T
System.out.println(file.isDirectory()); //是不是一個目錄 F
}

洗掉
public static void main(String[] args) {
File file = new File("d:\\news1.txt");
if(!file.exists()){
System.out.println("d:\\nes1.txt");
}else{
if(file.delete()){ // delete洗掉檔案
System.out.println("洗掉成功");
}else{
System.out.println("洗掉失敗");
}
}
}
創建一級目錄
public static void main(String[] args) {
// 注意在Java里目錄(檔案夾)也算是檔案
File file = new File("d:\\demo02");
if(file.exists()){
System.out.println("檔案夾存在");
}else{
file.mkdir(); //創建單極目錄,當然mkdirs也行
}
}
創建多級目錄
public static void main(String[] args) {
// 注意在Java里目錄(檔案夾)也算是檔案
File file = new File("d:\\demo02\\demo03");
if(file.exists()){
System.out.println("檔案夾存在");
}else{
file.mkdirs(); //創建多級目錄
}
}
IO流
原理



注:1. Java的IO流總共涉及40多個類,實際上非常規則,都是從上面的四個抽象基類派生的,
2. 由這四個類派生出來的子類名稱都是以其父類名作為子類名后綴,
流與檔案的類似關系:

InputStream

FileInputStream
用read讀取單個位元組 read()
public static void main(String[] args) { //用read讀取單個位元組
int readData = 0; //注意這里,readData初始化為int型別,因為讀入的是字符碼
FileInputStream fis = null; //不初始化會報錯
try {
//創建 FileInputStream物件,用于讀取檔案
fis = new FileInputStream("d:\\test1.txt");
//從該輸入流讀取一個位元組的資料,如果沒有輸入可用,此方法回傳-1,表示讀取完畢
while((readData = fis.read()) != -1){ //持續讀入
System.out.print((char)readData); //輸出時轉換為char型別
}
} catch (IOException e) {
//IOException包括一切IO例外,用別的read和FileInputStream只能管一個
e.printStackTrace();
} finally {
//關閉檔案流,釋放資源
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是這種方法不適用于漢字的讀取,因為在UTF-8中,一個漢字是由二到三個字符碼編成的,如果按位元組讀取,會導致亂碼,
用read讀取多個位元組:read(byte[]) 每次能讀取byte陣列容量(N)個位元組
public static void main(String[] args) {
int readLen;
byte[] buf = new byte[8]; //一次讀取8個位元組
FileInputStream fis = null; //不初始化會報錯
try {
//創建 FileInputStream物件,用于讀取檔案
fis = new FileInputStream("d:\\test1.txt");
//從該輸入流讀取一個位元組的資料,如果沒有輸入可用,此方法回傳-1,表示讀取完畢
while((readLen = fis.read(buf)) != -1){ //如果讀取正常,回傳實際讀取的位元組數
System.out.print(new String(buf,0,readLen));
//注意不能用buf.length,會有額外位元組
}
} catch (IOException e) {
//IOException包括一切IO例外,用別的read和FileInputStream只能管一個
e.printStackTrace();
} finally {
//關閉檔案流,釋放資源
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutPutStream

FileOutputStream
public static void main(String[] args) {
String filePath = "d:\\a.txt";
//如果不存在這個檔案,會自動創建
FileOutputStream fos = null;
String str = "Hello,world!";
try {
fos = new FileOutputStream(filePath);
// fos.write('a'); 輸入一個字符
// 寫入字串方法:str.getBytes() 可以把 字串-> 位元組陣列
fos.write(str.getBytes());
fos.write(str.getBytes(),2,3);
//從索引為2的地方開始追加3個位元組,
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注:1. write(byte[] b,int off,int len){} 將len個位元組從off索引開始寫入檔案,
2. new FileOutputStream(filePath) 這樣的創建方式會把寫入的內容覆寫原來的內容,
3. new FileOutputStream(filePath,true) 這樣的創建方式,當寫入內容會追加到檔案后面,
4. FileOutputStream和FileInputStream都是位元組處理流,可以處理二進制檔案和文本檔案,
復制一個檔案(影像等)
public static void main(String[] args) {
FileInputStream fileInputStream = null; //輸入流
FileOutputStream fileOutputStream = null; //輸出流
try {
fileOutputStream = new FileOutputStream("d:\\test2.txt");
fileInputStream = new FileInputStream("d:\\test1.txt");
byte[] b = new byte[1024]; //邊讀邊寫
int len;
while((len = fileInputStream.read(b)) != -1){
fileOutputStream.write(b,0,len); //不能用b,因為可能有沒有用到的空間
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileOutputStream.close();
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

FileReader



FileWriter


FileWriter和FileReader是節點流中的字符流,處理字符,不能處理二進制檔案,只能處理文本檔案,
節點流和處理流

節點流圖解:

包裝流圖解:


對包裝流的模擬:
class BufferReader_{ //這個就是個包裝類
private Reader_ reader_; //包裝了一個Reader_型別的屬性
public Test(Reader_ reader_) {
this.reader_ = reader_;
} //構造器
public static void main(String[] args) {
BufferReader_ test = new BufferReader_(new StringReader_());
//根據多型可以傳入各種 節點流
test.reader_.readString(); //呼叫相關方法
}
}
abstract class Reader_{
public void readFile(){}
public void readString(){}
} //定義抽象類,后面在呼叫時,用動態系結機制
class FileReader_ extends Reader_{ //檔案讀取類
@Override
public void readFile(){
System.out.println("對檔案進行讀取");
}
}
class StringReader_ extends Reader_{ //字串讀取類
@Override
public void readString() {
System.out.println("對字串進行讀取");
}
}
也可以在 BufferReader_中 添加各種讀取方法:
public void readFiles(int num){
for(int i=0;i<num;i++){
reader_.readFile();
}
}
BufferedReader


注:1. readLine方法讀取一行,讀取完畢回傳null,
2. BufferedReader的關閉只需要關閉包裝流,節點流在包裝流關閉后會自動關閉,

注:
new FileWriter(filePath,true); //表示以追加的方式寫入
new FileWriter(filePath); // 表示以覆寫的方式寫入
2. BufferedReader 和 BufferedWriter 是安裝字符操作,不要去操作二進制檔案(聲音,視頻,doc等),可能造成檔案損壞,
BufferedInputStream和BufferedOutputStream


前面的Buffered使用writer和reader,這個Buffered使用 FileInputStream和FileOutputStream



ObjectInputStream和ObjectOutputStream
假如說我們只想把"10"這個數存到檔案里,那么只是保存值,用不上ObjectInputStream,但如果想把值和資料型別都保存,比如Dog類或者"int a = 10",那么就需要用到了,


ObjectOutputStream提供 序列化功能, ObjectInputStream提供 反序列化功能,



注:Dog類需要實作Serializable介面
class Dog implements Serializable{
...
}


值得注意的是:1. 讀取順序必須和write順序一致, 2. 讀取自定義類時,這個類需要能被訪問到,
3. ObjectInputStream和ObjectOutputStream都是只關閉外流就可以了,

標準輸入輸出流
public final static InputStream in = null;
public final static PrintStream out = null;
System.in 編譯型別:InputStream,運行型別:BufferedInputStream,表示的是標準輸入 鍵盤
System.out 編譯型別:PrintStream,運行型別:PrintStream, 表示的是標準輸入 顯示幕
轉換流
默認情況下,讀取檔案是按照UTF-8編碼,如果檔案按照別的方式編碼,就很容易讀取到亂碼,


包裝:其實就是轉換,
String filePath = "d:\\a.txt";
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath,"gbk"));
//注意檔案編碼格式是啥,就轉化成啥格式
BufferedReader br = new BufferedReader(isr); //包裝轉換流,轉換成字符流
String s = br.readLine();
br.close(); //關閉外層流

列印流
只有輸出流,沒有輸入流,


PrintStream out = new PrintStream(System.out);
out.println("hello");
out.write("你好,世界".getBytes());
//print底層呼叫的是write,所以可以直接呼叫write進行列印
out.close(); //注意由于out是System.out,這個一結束,sout就不能用了
System.out.println("wowowo"); //無法輸出
PrintStream out2 = new PrintStream("d:\\a.txt");
System.setOut(out2);
//修改列印流輸出的位置
System.out.println("1111"); //輸出到檔案當中
public static void main(String[] args) throws IOException {
FileWriter fileWriter = new FileWriter("d:\\a.txt");
PrintWriter printWriter = new PrintWriter(fileWriter);
printWriter.print("hello,world!!!!!!");
printWriter.flush();
//printWriter.close(); //flush或者close呼叫一個,才能輸入進去
}
Properties

注:鍵值對不需要有空格,值不需要用引號引起來,值的默認型別是String,



store方法的第二個引數是注釋,null表示沒有注釋,在store方法中,如果沒有這個檔案就是創建,如果有這個檔案就是修改,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/336232.html
標籤:java
