1. 程式人生 > >java之LineNumberReader類,裝飾者模式,列印流,合併流(檔案合併和分割)和第三方工具類(FileNameUtils)

java之LineNumberReader類,裝飾者模式,列印流,合併流(檔案合併和分割)和第三方工具類(FileNameUtils)

一.LineNumberReader類

public class Kll {
	public static void main(String[] args) throws IOException {
	        File file = new File("/Users/lanou/Desktop/Test/happy.txt");
		FileReader in = new FileReader(file);
		LineNumberReader lReader = new LineNumberReader(in);
		String string = null;
		// 設定行號(預設從1開始)
		lReader.setLineNumber(100);
		while ((string = lReader.readLine()) != null) {
			System.out.println(lReader.getLineNumber() + ":" + string);
		}
		lReader.close();
	}
}

二.裝飾者類

  • 裝飾者模式(解耦 不讓類與類產生繼承的關係)

    • 對 物件的原有功能進行升級
  • 書寫步驟:

    • 1.明確被裝飾的物件.
    • 2.將被裝飾的物件,通過構造方法傳入裝飾類
      • 裝飾類中肯定有一個成員變數,就是被裝飾物件
    • 3.擁有被裝飾的物件,相當於可以呼叫該物件中的所有方法
      • 就可以對該方法進行升級
1.需求:	利用裝飾類完成                
	在校學生類 學習java,js,c++
	去培訓機構提升知識學習 H5
// 學習介面
interface Study{
	void study();
}
// 在校學生類
class Student implements Study{

	@Override
	public void study() {
		System.out.println("在校學生 學了c++,java,js");
	}
}
// 包裝自己,即裝飾類
class LoStudent implements Study{
	// 將被裝飾者宣告為成員變數
	private Student student;

	// 提供有參構造方法
	public LoStudent() {
		super();
		// TODO Auto-generated constructor stub
	}
	public LoStudent(Student student) {
		super();
		this.student = student;
	}
	
	// 對方法進行升級
	@Override
	public void study() {
		// 調原有學生學習方法
		student.study();
		// 裝飾新功能
		System.out.println("藍鷗進修學習H5");
	}
}
public class Kll {
	public static void main(String[] args) {
		Student student = new Student();
		LoStudent student1 = new LoStudent(student);
		student1.study();
	}
}
2.需求:利用裝飾者模式完成
	// 模擬LineNumberReader類 利用裝飾者模式 實現獲取設定行號功能
	// 被裝飾的物件是Reader類
	// 要裝飾的方法 單個字元讀取---->升級 能讀行
	// 在方法中新增記錄行號功能
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

// 模擬LineNumberReader類
class MyLineNumberReader{
	// 被裝飾物件
	private FileReader fr;
	// 行號 宣告屬相
	private int lineNumber;
	// 構造方法
	public MyLineNumberReader() {
		super();
	}
	public MyLineNumberReader(FileReader fr) {
		super();
		this.fr = fr;
	}
	// set/get方法
	public int getLineNumber() {
		return lineNumber;
	}
	public void setLineNumber(int lineNumber) {
		this.lineNumber = lineNumber;
	}
	
	// 功能升級 讀行升級
	public String newReaderLin() throws IOException {
		// 用到Reader中 讀單個字元的方法
		// 遇到\n 一行就結束了
		// 使用拼接字串將這行返回
		
		// 設定行號
		this.lineNumber++;
		int len = 0;
		StringBuffer sb = new StringBuffer();
		while ((len = fr.read()) != -1) {
			// 讀一行返回一行
			if (len != '\n') {
				// 拼接字元
				sb.append((char)len);
			}else {
				// 直接返回拼好的字串
				return sb.toString();
			}
			
		}
		// 迴圈不執行,檔案就讀完了 返回null
		return null;
	}
	
	// 提供關流的方法
	public void clo() throws IOException {
		fr.close();
	}
	
}
public class Kll {
	public static void main(String[] args) throws IOException {
		
		// 模擬LineNumberReader類 利用裝飾者模式 實現獲取設定行號功能
		// 被裝飾的物件是Reader類
		// 要裝飾的方法 單個字元讀取---->升級 能讀行
		// 在方法中新增記錄行號功能
		
		File file = new File("/Users/lanou/Desktop/Test/happy.txt");
		FileReader in = new FileReader(file);
		MyLineNumberReader mlnr = new MyLineNumberReader(in);
		String string = null;
		mlnr.setLineNumber(12);
		while ((string = mlnr.newReaderLin()) != null) {
			System.out.println(mlnr.getLineNumber() + ":" + string);
		}
		mlnr.clo();
	}
}

三.列印流

public class Kll{
	public static void main(String[] args) throws IOException {
	// 列印流(用位元組流)寫檔案
	       FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/new.txt");
		PrintStream ps = new PrintStream(fos);
		// 寫檔案
		ps.println("kll");
		ps.print(false);
		ps.print(100);
		ps.close();

	// 列印流(用字元流寫檔案)
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/new.txt");
		PrintWriter pw = new PrintWriter(fos, true);
		pw.println("分割");
		pw.println(100);
		pw.println(true);
		pw.close();
	}
}

需求:

  • 利用System.out 輸出到控制檯
  • 輸入quit 停止輸入
  • 列印到控制檯(不用Scanner) 程式碼如下:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
/*
 * 利用System.in 從控制檯就收
 * 利用System.out 輸出到控制檯
 * 輸入quit 停止輸入
 * 列印到控制檯(不用Scanner)
 */
// 卡住程式的 .read()方法
public class Kll {
	public static void main(String[] args) throws IOException {
		//fun1();
		//fun2();
		
		System.out.println("請輸入:");
		InputStream in = System.in;
		// 拼接字串
		StringBuffer sb = new StringBuffer();
		while (true) {
			// 讀
			int read = in.read();
			// 沒換行進行拼接
			if ((char)read != '\n') {
				sb.append((char)read);
				// 迴圈的結束條件
			}else {
				// 直接輸出到控制檯
				System.out.println(sb);
				// 清空sb字串
				sb.delete(0, sb.length());
			}if (sb.toString().equals("quit")) {
					break;
			}
			
		}
	}
}

四.合併流

位元組流 任何檔案都可以合併

第一種構造方法:兩個位元組流做引數

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class Demo05 {
	public static void main(String[] args) throws IOException {
	
		// 合併兩個檔案
		File f1 = new File("/Users/lanou/Desktop/Test11/new.txt");
		File f2 = new File("/Users/lanou/Desktop/Test11/kll.txt");
		FileInputStream fis1 = new FileInputStream(f1);
		FileInputStream fis2 = new FileInputStream(f2);
		 // 建立合併流
		SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
		// 寫入到新的檔案中  列印流寫
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/Long.txt");
		// 讀寫
		int len = 0;
		while ((len = sis.read()) != -1) {
			fos.write(len);
		}
		sis.close();
		fos.close();
	}
}

第二種構造方法:以Vector集合作為引數

public class Kll{
	public static void main(String[] args) throws IOException {
	        // 合併三個檔案 要求使用列印流寫入
		// 將要合併的檔案的三個流 新增到Vector集合中
		
		File f1 = new File("/Users/lanou/Desktop/Test11/new.txt");
		File f2 = new File("/Users/lanou/Desktop/Test11/kll.txt");
		File f3= new File("/Users/lanou/Desktop/Test11/Long.txt");
		// 建立位元組流 並且將三個流新增到集合中
		// 建立集合
		Vector<FileInputStream> vector = new Vector<>();
		vector.add(new FileInputStream(f1));
		vector.add(new FileInputStream(f2));
		vector.add(new FileInputStream(f3));
		// 獲取迭代器(列舉器)
		Enumeration<FileInputStream> elements = vector.elements();
		SequenceInputStream sis = new SequenceInputStream(elements);
		
		// 列印流寫入 
		// 轉換流 轉成 bufferReader
		InputStreamReader isr = new InputStreamReader(sis);
		BufferedReader br = new BufferedReader(isr);
		// 寫的
		FileWriter fw = new FileWriter("/Users/lanou/Desktop/Test11/Short.txt");
		// 列印流
		PrintWriter pw = new PrintWriter(fw, true);
		String str = null;
		while ((str = br.readLine()) != null) {
			// 寫
			pw.println(str);
		}
		pw.close();
		br.close();
	}
}

檔案的切割和合並 需求:

  • 將1張圖片 分割成多個檔案
  • 每個檔案按1M分割 1024*1024
  • 讀取圖片 一次讀1M
  • 將這1M 寫到一個新的檔案中
  • 分割完後
  • 再將分割的多個檔案合併成一個圖片
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class Kll {
	public static void main(String[] args) throws IOException {
		// 切割方法呼叫
		fun1();
		// 構建裝好的vector集合
		Vector<FileInputStream> vector = new Vector<>();
		for (int i = 1; i < 12; i++) {
			File file = new File("/Users/lanou/Desktop/Test11/歌曲" +  i + ".mp3");
			vector.addElement(new FileInputStream(file));
		}	
		
		// 獲取列舉器
		Enumeration<FileInputStream> elements = vector.elements();
		// 建立合併流
		SequenceInputStream sis = new SequenceInputStream(elements);
		
		// 寫出
		//File file = new File("/Users/lanou/Desktop/Test11/music.mp3");
		
		FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/music.mp3");
		int len = 0;
		byte[] bs = new byte[1024];
		while ((len = sis.read(bs)) != -1) {
			fos.write(bs, 0, len);
		}
		fos.close();
		sis.close();
	}

	public static void fun1() throws FileNotFoundException, IOException {
		// 切割檔案 1M儲存為一個檔案
		// 讀入流
		FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test11/歌曲.mp3");
		// 宣告陣列
		byte[] b = new byte[1024 * 1024];
		// 宣告迴圈變數 分割的檔名
		int num = 0;
		// 位元組有效長度
		int len = 0;
		while ((len = fis.read(b)) != -1) {
			// 檔名序號加加
			num++;
			// 建立寫的檔案流
			FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test11/歌曲" +  num + ".mp3");
			// 寫入的有效長度
			fos.write(b, 0, len);
			// 關閉流(寫一個關一個)
			fos.close();
		}
		fis.close();
	}
}

五.第三方工具類

 * commons-io-2.4 操作流的第三方工具
 * commons-io-2.4.jar 是倒入工程包
 * commons-io-2.4-sources 方法的原始碼

* FilenameUtils
 * 獲取路徑副檔名
 * static String getExtension(String filename)
 * 獲取檔案的名字
 * static String getName(String filename)
 * 判斷是不是這個副檔名
 * static boolean isExtension(String filename,String extension)
 * 
 * FileUtils類中
 * 複製資料夾
 * static void copyDirectoryToDirectory(File src,File desc)
 * 複製檔案
 * static void copyFile(File src,File desc)
 * 
 * IOUtils類中
 * 寫入字串到檔案
 * static void writeStringToFile(File src,String date)
 * 讀取檔案按字串
 * static String readFileToString(File src)
 * 
 * 寫入檔案 可以選取用什麼位元組流寫入
 * static void write(String data, OutputStream output)
 * 讀取檔案到集合中以字串形式
 * static List<String> readLines(InputStream input)