15.複製文本文件的5種方式案例
複製文本文件
分析:
複製數據。假設咱們知道用記事本打開並能夠讀懂,就用字符流。不然用字節流。
經過該原理,咱們知道咱們應該採用字符流更方便一些。
而字符流有5種方式。因此作這個題目咱們有5種方式。推薦掌握第5種。
數據源:
c:\\a.txt -- FileReader -- BufferdReader
目的地:
d:\\b.txt -- FileWriter -- BufferedWriter
=======================================
public static void main(String[] args) throws IOException {
String srcString = "c:\\a.txt";
String destString = "d:\\b.txt";
// method1(srcString, destString);
// method2(srcString, destString);
// method3(srcString, destString);
// method4(srcString, destString);
method5(srcString, destString);
}
// 字符緩衝流一次讀寫一個字符串
private static void method5(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
// 字符緩衝流一次讀寫一個字符數組
private static void method4(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
bw.close();
br.close();
}
// 字符緩衝流一次讀寫一個字符
private static void method3(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
int ch = 0;
while ((ch = br.read()) != -1) {
bw.write(ch);
}
bw.close();
br.close();
}
// 基本字符流一次讀寫一個字符數組
private static void method2(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fw.close();
fr.close();
}
// 基本字符流一次讀寫一個字符
private static void method1(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
16.複製圖片的4種方式案例
複製圖片
分析:
複製數據。假設咱們知道用記事本打開並能夠讀懂,就用字符流。不然用字節流。
而字節流有4種方式。因此作這個題目咱們有4種方式。推薦掌握第4種。
數據源:
c:\\a.jpg -- FileInputStream -- BufferedInputStream
目的地:
d:\\b.jpg -- FileOutputStream -- BufferedOutputStream
==========================================
public static void main(String[] args) throws IOException {
// 使用字符串做爲路徑
// String srcString = "c:\\a.jpg";
// String destString = "d:\\b.jpg";
// 使用File對象作爲參數
File srcFile = new File("c:\\a.jpg");
File destFile = new File("d:\\b.jpg");
// method1(srcFile, destFile);
// method2(srcFile, destFile);
// method3(srcFile, destFile);
method4(srcFile, destFile);
}
// 字節緩衝流一次讀寫一個字節數組
private static void method4(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
// 字節緩衝流一次讀寫一個字節
private static void method3(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
bos.close();
bis.close();
}
// 基本字節流一次讀寫一個字節數組
private static void method2(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fos.close();
fis.close();
}
// 基本字節流一次讀寫一個字節
private static void method1(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}
fos.close();
fis.close();
}
==============================================
17.把集合中的數據存儲到文本文件案例 ArrayListToFile
需求:把ArrayList集合中的字符串數據存儲到文本文件
分析:
經過題目的意思咱們可以知道例如如下的一些內容。
ArrayList集合裏存儲的是字符串。
遍歷ArrayList集合,把數據獲取到。
而後存儲到文本文件裏。
文本文件說明使用字符流。
數據源:
ArrayList<String> -- 遍歷獲得每一個字符串數據
目的地:
a.txt -- FileWriter -- BufferedWriter
=================================================
public static void main(String[] args) throws IOException {
// 封裝數據與(建立集合對象)
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
// 封裝目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
// 遍歷集合
for (String s : array) {
// 寫數據
bw.write(s);
bw.newLine();
bw.flush();
}
// 釋放資源
bw.close();
}
======================================
18.把文本文件裏的數據存儲到集合中案例 FileToArrayList
需求:從文本文件裏讀取數據(每一行爲一個字符串數據)到集合中。並遍歷集合
*
* 分析:
* 經過題目的意思咱們可以知道例如如下的一些內容,
* 數據源是一個文本文件。
* 目的地是一個集合。
* 而且元素是字符串。
*
* 數據源:
* b.txt -- FileReader -- BufferedReader
* 目的地:
* ArrayList<String>
======================================
public static void main(String[] args) throws IOException {
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
// 封裝目的地(建立集合對象)
ArrayList<String> array = new ArrayList<String>();
// 讀取數據存儲到集合中
String line = null;
while ((line = br.readLine()) != null) {
array.add(line);
}
// 釋放資源
br.close();//別忘記這一步
// 遍歷集合
for (String s : array) {
System.out.println(s);
}
}
===========================================
19.隨機獲取文本文件裏的姓名案例
需求:我有一個文本文件裏存儲了幾個名稱。請你們寫一個程序實現隨機獲取一我的的名字。
分析:
A:把文本文件裏的數據存儲到集合中
B:隨機產生一個索引
C:依據該索引獲取一個值
public static void main(String[] args) throws IOException {
// 把文本文件裏的數據存儲到集合中
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
ArrayList<String> array = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null) {
array.add(line);
}
br.close();
// 隨機產生一個索引
Random r = new Random();
int index = r.nextInt(array.size());
// 依據該索引獲取一個值
String name = array.get(index);
System.out.println("該幸運者是:" + name);
}
==========================================
20.複製單級目錄案例
/*
* 需求:複製單極目錄
*
* 數據源:e:\\demo
* 目的地:e:\\test
*
* 分析:
* A:封裝文件夾
* B:獲取該文件夾下的所有文本的File數組
* C:遍歷該File數組。獲得每一個File對象
* D:把該File進行復制
*/
public class CopyFolderDemo {
public static void main(String[] args) throws IOException {
// 封裝文件夾
File srcFolder = new File("e:\\demo");
// 封裝目的地
File destFolder = new File("e:\\test");
// 假設目的地目錄不存在,就建立(必定要注意這個問題)
if (!destFolder.exists()) {
destFolder.mkdir();
}
// 獲取該文件夾下的所有文本的File數組
File[] fileArray = srcFolder.listFiles();
// 遍歷該File數組。獲得每一個File對象
for (File file : fileArray) {
// System.out.println(file);
// 數據源:e:\\demo\\e.mp3
// 目的地:e:\\test\\e.mp3
String name = file.getName(); // e.mp3
File newFile = new File(destFolder, name); // e:\\test\\e.mp3
copyFile(file, newFile);
}
}
private static void copyFile(File file, File newFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
file));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(newFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
=====================================================
注意:文件不存在可以本身主動建立。但是目錄不存在不會本身主動建立,所以
if (!destFolder.exists()) {
destFolder.mkdir();
}
21.複製指定文件夾下指定後綴名的文件並改動名稱案例
數據源
/*
* 需求:複製指定文件夾下的指定文件。並改動後綴名。
* 指定的後綴名是:.jad
* 指定的文件夾是:jad
*
* 數據源:e:\\java\\A.java
* 目的地:e:\\jad\\A.jad
*
* 分析:
* A:封裝文件夾
* B:獲取該文件夾下的java文件的File數組
* C:遍歷該File數組,獲得每一個File對象
* D:把該File進行復制
* E:在目的地文件夾下更名
*/
public class CopyFolderDemo {
public static void main(String[] args) throws IOException {
// 封裝文件夾
File srcFolder = new File("e:\\java");
// 封裝目的地
File destFolder = new File("e:\\jad");
// 假設目的地文件夾不存在,就建立
if (!destFolder.exists()) {
destFolder.mkdir();
}
// 獲取該文件夾下的java文件的File數組
File[] fileArray = srcFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile() && name.endsWith(".java");
}
});
// 遍歷該File數組。獲得每一個File對象
for (File file : fileArray) {
// System.out.println(file);
// 數據源:e:\java\DataTypeDemo.java
// 目的地:e:\\jad\DataTypeDemo.java
String name = file.getName();
File newFile = new File(destFolder, name);
copyFile(file, newFile);
}
// 在目的地文件夾下更名
File[] destFileArray = destFolder.listFiles();
for (File destFile : destFileArray) {
// System.out.println(destFile);
// e:\jad\DataTypeDemo.java
// e:\\jad\\DataTypeDemo.jad
String name =destFile.getName(); //DataTypeDemo.java
String newName = name.replace(".java", ".jad");//DataTypeDemo.jad
File newFile = new File(destFolder,newName);
destFile.renameTo(newFile);
}
}
private static void copyFile(File file, File newFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
file));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(newFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
==================================
執行後演示樣例
而本人先前本身模仿了一個。功能稍微不同
數據源
/*
* 需求:複製指定文件夾下的指定文件,並改動後綴名
* 這個文件是我本人作的,問題是:目錄複製沒處理好(copyDirectory方法略繁瑣 )
*
* 數據源:g:\\java\\A.java
* 目的地:f:\\jad\\A.jad
*/
public class CopyFolderDemo2 {
public static void main(String[] args) throws IOException {
// 封裝文件夾
File srcFolder = new File("g:\\java");
File desFolder = new File("f:\\jad");
if (!desFolder.exists()) {
desFolder.mkdir();
}
File[] files = srcFolder.listFiles();
for (File f : files) {
if (!f.isDirectory()) {
String name = f.getName();
File newFile = new File(desFolder, name);
copyFile(f, newFile);
modifyFile(desFolder);
} else {
String folderName = f.getName();
String desFolderName = desFolder.getName();
copyDirectory(desFolder, folderName);
}
}
}
private static void copyDirectory(File desFolder, String folderName) {
File newFolder = new File(desFolder, folderName);
newFolder.mkdirs();
}
private static void modifyFile(File desFolder) {
File[] files = desFolder.listFiles();
for (File f : files) {
if (!f.isDirectory()) {
String name = f.getName();
if (name.endsWith(".java")) {
int index = name.indexOf(".");
String fileNameString = name.substring(0, index);
String newNameString = fileNameString.concat(".jad");
File newFile = new File(desFolder, newNameString);
f.renameTo(newFile);
}
}
}
}
private static void copyFile(File f, File newFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
}
}
執行演示樣例
22.複製多級目錄案例
/*
* 需求:複製多極目錄
*
* 數據源:E:\JavaSE\day21\code\demos
* 目的地:E:\\
*
* 分析:
* A:封裝數據源File
* B:封裝目的地File
* C:推斷該File是目錄仍是文件
* a:是目錄
* 就在目的地文件夾下建立該文件夾
* 獲取該File對象下的所有文件或者目錄File對象
* 遍歷獲得每一個File對象
* 回到C
* b:是文件
* 就複製(字節流)
*/
public class CopyFoldersDemo {
public static void main(String[] args) throws IOException {
// 封裝數據源File
File srcFile = new File("E:\\JavaSE\\day21\\code\\demos");
// 封裝目的地File
File destFile = new File("E:\\");
// 複製目錄的功能
copyFolder(srcFile, destFile);
}
private static void copyFolder(File srcFile, File destFile)
throws IOException {
// 推斷該File是目錄仍是文件
if (srcFile.isDirectory()) {
// 目錄
File newFolder = new File(destFile, srcFile.getName());
newFolder.mkdir();
// 獲取該File對象下的所有文件或者目錄File對象
File[] fileArray = srcFile.listFiles();
for (File file : fileArray) {
copyFolder(file, newFolder);
}
} else {
// 文件
File newFile = new File(destFile, srcFile.getName());
copyFile(srcFile, newFile);
}
}
private static void copyFile(File srcFile, File newFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(newFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
23.鍵盤錄入學生信息依照總分排序並寫入文本文件案例
Student類例如如下
===================
public class Student {
// 姓名
private String name;
// 語文成績
private int chinese;
// 數學成績
private int math;
// 英語成績
private int english;
public Student() {
super();
}
public Student(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum() {
return this.chinese + this.math + this.english;
}
}
==========================================
測試類
=====
public class StudentDemo {
public static void main(String[] args) throws IOException {
// 建立集合對象
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s2.getSum() - s1.getSum();
int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;
int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())
: num4;
return num5;
}
});
// 鍵盤錄入學生信息存儲到集合
for (int x = 1; x <= 5; x++) {
Scanner sc = new Scanner(System.in);
System.out.println("請錄入第" + x + "個的學習信息");
System.out.println("姓名:");
String name = sc.nextLine();
System.out.println("語文成績:");
int chinese = sc.nextInt();
System.out.println("數學成績:");
int math = sc.nextInt();
System.out.println("英語成績:");
int english = sc.nextInt();
// 建立學生對象
Student s = new Student();
s.setName(name);
s.setChinese(chinese);
s.setMath(math);
s.setEnglish(english);
// 把學生信息加入到集合
ts.add(s);
}
// 遍歷集合,把數據寫到文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt"));
bw.write("學生信息例如如下:");
bw.newLine();
bw.flush();
bw.write("姓名,語文成績,數學成績,英語成績");
bw.newLine();
bw.flush();
for (Student s : ts) {
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append(",").append(s.getChinese())
.append(",").append(s.getMath()).append(",")
.append(s.getEnglish());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
// 釋放資源
bw.close();
System.out.println("學習信息存儲完成");
}
}
24.把一個文件裏的字符串排序後再寫入還有一個文件案例
已知s.txt文件裏有這種一個字符串:「hcexfgijkamdnoqrzstuvwybpl」
請編敲代碼讀取數據內容,把數據排序後寫入ss.txt中。
分析:
A:把s.txt這個文件給作出來
B:讀取該文件的內容。存儲到一個字符串中
C:把字符串轉換爲字符數組
D:對字符數組進行排序
E:把排序後的字符數組轉換爲字符串
F:把字符串再次寫入ss.txt中
public static void main(String[] args) throws IOException {
// 讀取該文件的內容,存儲到一個字符串中
BufferedReader br = new BufferedReader(new FileReader("s.txt"));
String line = br.readLine();
br.close();
// 把字符串轉換爲字符數組
char[] chs = line.toCharArray();
// 對字符數組進行排序
Arrays.sort(chs);
// 把排序後的字符數組轉換爲字符串
String s = new String(chs);
// 把字符串再次寫入ss.txt中
BufferedWriter bw = new BufferedWriter(new FileWriter("ss.txt"));
bw.write(s);
bw.newLine();
bw.flush();
bw.close();
}
//注意一下readLine(無需flush) 和 newLine,還有字符數組轉換爲字符串
25.本身定義類模擬BufferedReader的readLine()功能案例(有必定難度)
先寫MyBufferedReader類
================================================================
/*
* 用Reader模擬BufferedReader的readLine()功能
*
* readLine():一次讀取一行,依據換行符推斷是否結束,僅僅返回內容,不返回換行符
*/
public class MyBufferedReader {
private Reader r;
public MyBufferedReader(Reader r) {
this.r = r;
}
/*
*/
public String readLine() throws IOException {
/*
* 我要返回一個字符串,我該怎麼辦呢? 咱們必須去看看r對象能夠讀取什麼東西呢? 兩個讀取方法,一次讀取一個字符或者一次讀取一個字符數組
* 那麼。咱們要返回一個字符串。用哪一個方法比較好呢? 咱們很是easy想到字符數組比較好,但是問題來了。就是這個數組的長度是多長呢?
* 根本就沒有辦法定義數組的長度,你定義多長都不合適。 因此,僅僅能選擇一次讀取一個字符。
* 但是呢。這樣的方式的時候。咱們再讀取下一個字符的時候,上一個字符就丟失了 因此,咱們又應該定義一個暫時存儲空間把讀取過的字符給存儲起來。
* 這個用誰比較和是呢?數組。集合,字符串緩衝區三個可供選擇。
* 通過簡單的分析。終於選擇使用字符串緩衝區對象。並且使用的是StringBuilder
*/
StringBuilder sb = new StringBuilder();
// 作這個讀取最麻煩的是推斷結束,但是在結束以前應該是一直讀取,直到-1
/*
hello
world
java
104101108108111
119111114108100
1069711897
*/
int ch = 0;
while ((ch = r.read()) != -1) { //104,101,108,108,111
if (ch == '\r') {
continue;//必須\r\n同一時候存在的時候纔算換行,所以這裏繼續
}
if (ch == '\n') {
return sb.toString(); //hello
} else {
sb.append((char)ch); //hello//必須轉換。否則就會104,101,108,108,111
}
}
// 爲了防止數據丟失,推斷sb的長度不能大於0//反正就是無論怎樣,僅僅要有數據了。最後都來拼一下反正數據丟失
if (sb.length() > 0) {
return sb.toString();
}
return null;
}
/*
* 先寫一個關閉方法
*/
public void close() throws IOException {
this.r.close();//表面上調用Buffered……的方法。實際上仍是用r自身的close方法
}
}
============================================================
但是的話,。
如下是測試類
===========================================
/*
* 測試MyBufferedReader的時候。你就把它看成BufferedReader同樣的使用
*/
public class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
MyBufferedReader mbr = new MyBufferedReader(new FileReader("my.txt"));
String line = null;
while ((line = mbr.readLine()) != null) {
System.out.println(line);
}
mbr.close();
// System.out.println('\r' + 0); // 13//經過加0的方法可以查看字符相應的數字編碼
// System.out.println('\n' + 0);// 10
}
}
==============================
26.LineNumberReader的使用案例
由上圖可知。其父類是BufferedReader
BufferedReader
|--LineNumberReader
public int getLineNumber()得到當前行號。
public void setLineNumber(int lineNumber)
public static void main(String[] args) throws IOException {
LineNumberReader lnr = new LineNumberReader(new FileReader("my.txt"));
// 從10開始才比較好
// lnr.setLineNumber(10);
// System.out.println(lnr.getLineNumber());
// System.out.println(lnr.getLineNumber());
// System.out.println(lnr.getLineNumber());
String line = null;
while ((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + ":" + line);
}
lnr.close();
}
默認
set以後
(本身定義類模擬LineNumberReader的獲取行號功能案例省略==)
day21筆記補充
IO流小結(掌握)
IO流
|--字節流
|--字節輸入流
InputStream
int read():一次讀取一個字節
int read(byte[] bys):一次讀取一個字節數組
|--FileInputStream
|--BufferedInputStream
|--字節輸出流
OutputStream
void write(int by):一次寫一個字節
void write(byte[] bys,int index,int len):一次寫一個字節數組的一部分
|--FileOutputStream
|--BufferedOutputStream
|--字符流
|--字符輸入流
Reader
int read():一次讀取一個字符
int read(char[] chs):一次讀取一個字符數組
|--InputStreamReader
|--FileReader
|--BufferedReader
String readLine():一次讀取一個字符串
|--字符輸出流
Writer
void write(int ch):一次寫一個字符
void write(char[] chs,int index,int len):一次寫一個字符數組的一部分
|--OutputStreamWriter
|--FileWriter
|--BufferedWriter
void newLine():寫一個換行符
void write(String line):一次寫一個字符串
今天寫過的案例(理解 練習一遍)
A:複製文本文件 5種方式(掌握)
B:複製圖片(二進制流數據) 4種方式(掌握)
C:把集合中的數據存儲到文本文件
D:把文本文件裏的數據讀取到集合並遍歷集合
E:複製單級目錄
F:複製單級目錄中指定的文件並改動名稱
回想一下批量改動名稱
G:複製多級目錄
H:鍵盤錄入學生信息依照總分從高到低存儲到文本文件
I:把某個文件裏的字符串排序後輸出到還有一個文本文件裏
J:用Reader模擬BufferedReader的特有功能
K:模擬LineNumberReader的特有功能
day22
1.登陸註冊案例IO版實現
簡要給代碼,詳細本身排錯。敲。
與集合的註冊案例想比,UserDaoImpl不同,其他的都同樣。
=========================================
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import cn.itcast.dao.UserDao;
import cn.itcast.pojo.User;
/**
* 這是用戶操做的詳細實現類(IO版)
*
* @author 風清揚
* @version V1.1
*
*/
public class UserDaoImpl implements UserDao {
// 爲了保證文件一載入就建立,在這裏如下的紅色部分使用了static靜態代碼塊,類一載入就運行而且僅僅運行一次
private static File file = new File("user.txt");
static {
try {
file.createNewFile();
} catch (IOException e) {
System.out.println("建立文件失敗");
// e.printStackTrace();
}
}
@Override
public boolean isLogin(String username, String password) {
boolean flag = false;
BufferedReader br = null;
try {
// br = new BufferedReader(new FileReader("user.txt"));
br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null) {
// username=password
String[] datas = line.split("=");//利用了字符串的方法。利用正則表達式拆分字符串
if (datas[0].equals(username) && datas[1].equals(password)) {
flag = true;
break;
}
}
} catch (FileNotFoundException e) {//本類所有的異常僅僅能try……catch處理,因爲拋(throws)的話會比較麻煩而且影響其餘的類。違背了獨立改動且不影響其餘類的初衷
System.out.println("用戶登陸找不到信息所在的文件");
// e.printStackTrace();
} catch (IOException e) {
System.out.println("用戶登陸失敗");
// e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
System.out.println("用戶登陸釋放資源失敗");
// e.printStackTrace();
}
}
}
return flag;
}
@Override
public void regist(User user) {
/*
* 爲了讓註冊的數據能夠有必定的規則,我就自定義了一個規則: username=password
*/
BufferedWriter bw = null;
try {
// bw = new BufferedWriter(new FileWriter("user.txt"));
// bw = new BufferedWriter(new FileWriter(file));
// 爲了保證數據是追加寫入,必須加true
bw = new BufferedWriter(new FileWriter(file, true));//不加true的話。又一次建立文件會形成上一次的註冊信息丟失
bw.write(user.getUsername() + "=" + user.getPassword());
bw.newLine();
bw.flush();
} catch (IOException e) {
System.out.println("用戶註冊失敗");
// e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
System.out.println("用戶註冊釋放資源失敗");
// e.printStackTrace();
}
}
}
}
}
附:String的split方法以及user.txt裏面保存的信息
2.數據輸入輸出流
可以讀寫基本數據類型的數據
數據輸入流:DataInputStream
DataInputStream(InputStream in)
數據輸出流:DataOutputStream
DataOutputStream(OutputStream out)
===================================
public static void main(String[] args) throws IOException {
// 寫
// write();
// 讀
read();
}
private static void read() throws IOException {
// DataInputStream(InputStream in)
// 建立數據輸入流對象
DataInputStream dis = new DataInputStream(
new FileInputStream("dos.txt"));
// 讀數據
byte b = dis.readByte();
short s = dis.readShort();
int i = dis.readInt();
long l = dis.readLong();
float f = dis.readFloat();
double d = dis.readDouble();
char c = dis.readChar();
boolean bb = dis.readBoolean();
// 釋放資源
dis.close();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(c);
System.out.println(bb);
}
private static void write() throws IOException {
// DataOutputStream(OutputStream out)
// 建立數據輸出流對象
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"dos.txt"));
// 寫數據了
dos.writeByte(10);
dos.writeShort(100);
dos.writeInt(1000);
dos.writeLong(10000);
dos.writeFloat(12.34F);//有一個類型轉換
dos.writeDouble(12.56);
dos.writeChar('a');
dos.writeBoolean(true);
// 釋放資源
dos.close();
}
==========================================
注意一個問題,假設僅僅有DataOutputStream來寫文件。直接雙擊打開文件。讀到的數據是亂碼
3.內存操做流的概述和解說
內存操做流:用於處理暫時存儲信息的。程序結束,數據就從內存中消失。
字節數組:
ByteArrayInputStream
ByteArrayOutputStream
字符數組:
CharArrayReader
CharArrayWriter
字符串:
StringReader
StringWriter
對於ByteArrayOutputStream:
此類實現了一個輸出流,當中的數據被寫入一個 byte 數組。緩衝區會隨着數據的不斷寫入而本身主動增加。可以使用toByteArray()
和 toString()
獲取數據。
關閉 ByteArrayOutputStream
無效。此類中的方法在關閉此流後仍可被調用,而不會產生不論什麼 IOException
。(說白了就是不用close方法了)
對於ByteArrayInputStream
:
ByteArrayInputStream
包括一個內部緩衝區,該緩衝區包括從流中讀取的字節。
內部計數器跟蹤 read
方法要提供的下一個字節。
關閉 ByteArrayInputStream
無效。
此類中的方法在關閉此流後仍可被調用。而不會產生不論什麼 IOException
。
public static void main(String[] args) throws IOException {
// 寫數據
// ByteArrayOutputStream()
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 寫數據
for (int x = 0; x < 10; x++) {
baos.write(("hello" + x).getBytes());
}
// 釋放資源
// 經過查看源代碼咱們知道這裏什麼都沒作,因此根本需要close()
// baos.close();
// public byte[] toByteArray()
byte[] bys = baos.toByteArray();
// 讀數據
// ByteArrayInputStream(byte[] buf)
ByteArrayInputStream bais = new ByteArrayInputStream(bys);
int by = 0;
while ((by = bais.read()) != -1) {
System.out.print((char) by);
}
// bais.close();//不需要close
}
4.打印流的概述和特色
打印流
字節流打印流 PrintStream
字符打印流 PrintWriter
打印流的特色:
A:僅僅有寫數據的。沒有讀取數據。僅僅能操做目的地,不能操做數據源。
C:假設啓動了本身主動刷新,能夠本身主動刷新。(假設不啓動的話。不刷新文件(就是flush或者close)裏面是沒有數據的)
D:該流是可以直接操做文本文件的。
FileInputStream
FileOutputStream
FileReader
FileWriter
PrintStream
PrintWriter
看API,查流對象的構造方法,假設同一時候有File類型和String類型的參數,通常來講就是可以直接操做文件的。
流:
基本流:就是能夠直接讀寫文件的
高級流:在基本流基礎上提供了一些其它的功能
==========================================
public static void main(String[] args) throws IOException {
// 做爲Writer的子類使用
PrintWriter pw = new PrintWriter("pw.txt");
pw.write("hello");
pw.write("world");
pw.write("java");
pw.close();//沒有這句話不出數據,因爲這不是本身主動刷新的(或者)
}
5.PrintWriter實現本身主動刷新和換行
可以操做隨意類型的數據。
print()
println()
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter("pw2.txt");
pw.print("hello");//print方法可接受隨意類型的數據
pw.print(100);
pw.print(true);
pw.close();
}
但以上的方法並無實現本身主動刷新
要實現本身主動刷新的話,
啓動本身主動刷新
PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);//要設置true
仍是應該調用println()的方法才幹夠(調用print本身主動刷新不了)
public static void main(String[] args) throws IOException {
// 建立打印流對象
// PrintWriter pw = new PrintWriter("pw2.txt");
PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);
// write()是搞不定的。怎麼辦呢?
// 咱們就應該看看它的新方法
// pw.print(true);
// pw.print(100);
// pw.print("hello");
pw.println("hello");
pw.println(true);
pw.println(100);
pw.close();
}
注意:println()
事實上等價于于:
bw.write();
bw.newLine();
bw.flush();
一句頂三句
6.打印流改進複製文本文件案例
需求:DataStreamDemo.java拷貝到Copy.java中
數據源:
DataStreamDemo.java -- 讀取數據 -- FileReader -- BufferedReader
目的地:
Copy.java -- 寫出數據 -- FileWriter -- BufferedWriter -- PrintWriter
public static void main(String[] args) throws IOException {
//曾經的版本號
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader(
"DataStreamDemo.java"));
//封裝目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
===============================================
public static void main(String[] args) {
// 打印流的改進版
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader(
"DataStreamDemo.java"));
// 封裝目的地
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
String line = null;
while((line=br.readLine())!=null){
pw.println(line);
}
pw.close();
br.close();
}
=============================================
7.標準輸入輸出流概述和輸出語句的本質------System.out
標準輸入輸出流
System類中的兩個成員變量:
public static final InputStream in 「標準」輸入流。
public static final PrintStream out 「標準」輸出流。
InputStream is = System.in;
PrintStream ps = System.out;
public static void main(String[] args) {
// 有這裏的解說咱們就知道了,這個輸出語句其本質是IO流操做,把數據輸出到控制檯。
System.out.println("helloworld");
// 獲取標準輸出流對象
PrintStream ps = System.out;
ps.println("helloworld");
ps.println();
// ps.print();//這種方法不存在
// System.out.println();
// System.out.print();
}
8.標準輸入輸出流概述和輸出語句的本質------System.in
public static void main(String[] args) throws IOException {
//獲取標準輸入流
InputStream is = System.in;
//我要一次獲取一行行不行呢?
//怎麼實現呢?
//要想實現。首先你得知道一次讀取一行數據的方法是哪一個呢?
//readLine()
//BufferedReader
//因此。你此次應該建立BufferedReader的對象,但是底層仍是的使用標準輸入流
// BufferedReader br = new BufferedReader(is);
//依照咱們的推想,現在應該可以了,但是卻報錯了
//緣由是:字符緩衝流僅僅能針對字符流操做,而你現在是字節流。因此不能是用?
//那麼。我還就想使用了,請你們給我一個解決方式?
//把字節流轉換爲字符流,而後在經過字符緩衝流操做
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br= new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//注意這裏的字節流轉換成字符流。利用了InputStreamReader轉換流
System.out.println("請輸入一個字符串:");
String line = br.readLine();
System.out.println("你輸入的字符串是:" + line);
System.out.println("請輸入一個整數:");
// int i = Integer.parseInt(br.readLine());
line = br.readLine();
int i = Integer.parseInt(line);
System.out.println("你輸入的整數是:" + i);
}
//利用上述代碼模仿了Scanner的鍵盤錄入功能
注意下面方法
9.輸出語句用字符緩衝流改進
public static void main(String[] args) throws IOException {
// 獲取標準輸入流
// // PrintStream ps = System.out;
// // OutputStream os = ps;//這個就是多態
//上面兩句簡化爲一句---- OutputStream os = System.out; // 多態
// // 我能不能依照剛纔使用標準輸入流的方式同樣把數據輸出到控制檯呢?
// OutputStreamWriter osw = new OutputStreamWriter(os);
// BufferedWriter bw = new BufferedWriter(osw);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
System.out));//合併爲一句
bw.write("hello");
bw.newLine();
// bw.flush();
bw.write("world");
bw.newLine();
// bw.flush();
bw.write("java");
bw.newLine();
bw.flush();
bw.close();
}
10.隨機訪問流概述和寫出數據
隨機訪問流:
RandomAccessFile類不屬於流,是Object類的子類。
但它融合了InputStream和OutputStream的功能。
支持對文件的隨機訪問讀取和寫入。
public RandomAccessFile(String name,String mode):第一個參數是文件路徑。第二個參數是操做文件的模式。
模式有四種,咱們最常用的一種叫"rw",這樣的方式表示我既可以寫數據,也可以讀取數據
這個RandomAccessFile類還可以讀和寫
11.隨機訪問流讀取數據和操做文件指針
===========================================
public static void main(String[] args) throws IOException {
read();
}
private static void read() throws IOException {
// 建立隨機訪問流對象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
int i = raf.readInt();
System.out.println(i);
// 該文件指針可以經過 getFilePointer方法讀取。並經過 seek 方法設置。
System.out.println("當前文件的指針位置是:" + raf.getFilePointer());//4
char ch = raf.readChar();
System.out.println(ch);
System.out.println("當前文件的指針位置是:" + raf.getFilePointer());//6
String s = raf.readUTF();
System.out.println(s);
System.out.println("當前文件的指針位置是:" + raf.getFilePointer());//14(原本是12的。多出來兩個字節的緣由可以看API,事實上是識別UTF編碼的兩個字節)
// 我不想重頭開始了,我就要讀取a,怎麼辦呢?
raf.seek(4);//從0開始計算
ch = raf.readChar();
System.out.println(ch);
}
======================================================
輸出演示樣例
12.合併流讀取兩個文件的內容拷貝到一個文件裏
合併流就是按順序讀取兩個文件而後合併到一個新的文件裏
public static void main(String[] args) throws IOException {
InputStream is1 = new FileInputStream("pw.txt");
InputStream is2 = new FileInputStream("pw2.txt");
// SequenceInputStream(InputStream s1, InputStream s2)
SequenceInputStream sis = new SequenceInputStream(is1, is2);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));
// 怎樣寫讀寫呢。事實上很是easy。你就依照曾經怎麼讀寫,現在仍是怎麼讀寫
byte[] bys = new byte[1024];
int len = 0;
while ((len = sis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
sis.close();
bos.close();
=============================================
執行演示樣例
執行前
執行後
13.合併流讀取多個文件的內容拷貝到一個文件裏
public static void main(String[] args) throws IOException {
// 需求:把如下的三個文件的內容拷貝到pwsum.txt中
// SequenceInputStream(Enumeration e)
// 經過簡單的回想咱們知道了Enumeration是Vector中的一個方法的返回值類型。
// Enumeration<E> elements()
Vector<InputStream> v = new Vector<InputStream>();
InputStream is1 = new FileInputStream("pw.txt");
InputStream is2 = new FileInputStream("pw2.txt");
InputStream is3 = new FileInputStream("pw3.txt");
v.add(is1);
v.add(is2);
v.add(is3);
Enumeration<InputStream> e = v.elements();
SequenceInputStream sis = new SequenceInputStream(e);//接收一個參數
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("pwsum.txt"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = sis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
sis.close();
bos.close();
}
14.序列化流和反序列化流的概述和使用
序列化流 ObjectOutputStream
反序列化流 ObjectInputStream
序列化流:把對象依照流同樣的方式存入文本文件或者在網絡中傳輸。對象 -- 流數據(ObjectOutputStream)
反序列化流:把文本文件裏的流對象數據或者網絡中的流對象數據還原成對象。流數據 -- 對象(ObjectInputStream)
首先。寫序列化流Demo的write方法。
public static void main(String[] args) throws IOException,
ClassNotFoundException {
// 由於咱們要對對象進行序列化,因此咱們先本身定義一個類
// 序列化數據事實上就是把對象寫到文本文件
write();
}
private static void write() throws IOException {
// 建立序列化流對象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"oos.txt"));
// 建立對象
Person p = new Person("林青霞", 27);
// public final void writeObject(Object obj)
oos.writeObject(p);
// 釋放資源
oos.close();
}
======================================================
而後,建立一個Person類
import java.io.Serializable;
public class Person implements Serializable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
============================
要說明的是。在Person類還沒實現 Serializable 這個接口的時候。執行會有異常
NotSerializableException:未序列化異常
查API
所以,要想沒報錯,必須在Person類中實現 Serializable 這個接口
但是:你會發現。沒有重寫不論什麼方法啊!!。
沒錯,因爲,原本就不用重寫不論什麼的方法!
解析例如如下:
類經過實現 java.io.Serializable 接口以啓用其序列化功能。未實現此接口的類將沒法使其不論什麼狀態序列化或反序列化。
該接口居然沒有不論什麼方法,相似於這樣的沒有方法的接口被稱爲標記接口。
而後。再次執行沒報錯後,直接打開文件是看不懂的
序列化的流必須要反序列的流"解鎖"才幹夠啊
最後。增長反序列流的代碼例如如下
執行(不報錯了)toString方法在Person類中已經重寫
注意這一步
// 還原對象
Object obj = ois.readObject();
obj儘管是Object類型,但是事實上是Person對象
但是。另外一個小問題
怎樣解決序列化時候的黃色警告線問題
當Person類進行了修改的時候(比方private int age 改成 int age)把代碼保存再次執行(僅僅執行讀操做而不進行第二次寫入)會報錯產生異常
產生的緣由:
爲何會有問題呢?
Person類實現了序列化接口。那麼它自己也應該有一個標記值。
這個標記值若是是100。
開始的時候:
Person.class -- id=100
wirte數據: oos.txt -- id=100
read數據: oos.txt -- id=100
現在:
Person.class -- id=200
wirte數據: oos.txt -- id=100
read數據: oos.txt -- id=100
解決問題的辦法:
咱們在實際開發中。可能還需要使用曾經寫過的數據,不能又一次寫入。怎麼辦呢?
每次改動java文件的內容的時候,class文件的id值都會發生改變。
而讀取文件的時候。會和class文件裏的id值進行匹配。因此。就會出問題。
但是呢,假設我有辦法。讓這個id值在java文件裏是一個固定的值,這樣,你改動文件的時候。這個id值還會發生改變嗎?
不會。現在的關鍵是我怎樣能夠知道這個id值怎樣表示的呢?
在Person類中加一下語句
private static final long serialVersionUID = -2071565876962058344L;
另外一個要注意的問題:
注意:
我一個類中可能有很是多的成員變量,有些我不想進行序列化。請問該怎麼辦呢?
使用transientkeyword聲明不需要序列化的成員變量
也就是用transientkeyword
把private int age改動爲
private transient int age;
而後執行會發現age的值爲0了,也就是說,age的值將不被記住是27了
15.Properties的概述和做爲Map集合的使用(注意:Properties並無泛型)
Properties:屬性集合類。是一個可以和IO流相結合使用的集合類。
Properties 可保存在流中或從流中載入。屬性列表中每個鍵及其相應值都是一個字符串。
是Hashtable的子類。說明是一個Map集合。
public static void main(String[] args) {
// 做爲Map集合的使用
// 如下這樣的使用方法是錯誤的,必定要看API,假設沒有<>,就說明該類不是一個泛型類,在使用的時候就不能加泛型
// Properties<String, String> prop = new Properties<String, String>();
Properties prop = new Properties();
// 加入元素
prop.put("it002", "hello");
prop.put("it001", "world");
prop.put("it003", "java");
// System.out.println("prop:" + prop);
// 遍歷集合,注意紅字是Object而不是String,因爲上面的put方法原本就是接受Object參數
Set<Object> set = prop.keySet();
for (Object key : set) {
Object value = prop.get(key);
System.out.println(key + "---" + value);
}
}
16.Properties的特殊功能使用
特殊功能:
public Object setProperty(String key,String value):加入元素
public String getProperty(String key):獲取元素
public Set<String> stringPropertyNames():獲取所有的鍵的集合
=========================
public static void main(String[] args) {
// 建立集合對象
Properties prop = new Properties();
// 加入元素
prop.setProperty("張三", "30");
prop.setProperty("李四", "40");
prop.setProperty("王五", "50");
// public Set<String> stringPropertyNames():獲取所有的鍵的集合
Set<String> set = prop.stringPropertyNames();
for (String key : set) {
String value = prop.getProperty(key);
System.out.println(key + "---" + value);
}
}
================================================
17.Properties的load()和store()功能
這裏的集合必須是Properties集合:
public void load(Reader reader):把文件中的數據讀取到集合中
public void store(Writer writer,String comments):把集合中的數據存儲到文件
=================================================
public static void main(String[] args) throws IOException {
myLoad();
myStore();
}
private static void myStore() throws IOException {
// 建立集合對象
Properties prop = new Properties();
prop.setProperty("林青霞", "27");
prop.setProperty("武鑫", "30");
prop.setProperty("劉曉曲", "18");
//public void store(Writer writer,String comments):把集合中的數據存儲到文件
Writer w = new FileWriter("name.txt");
prop.store(w, "helloworld");//這個helloworld僅僅是凝視的做用。。。
w.close();
}
private static void myLoad() throws IOException {
Properties prop = new Properties();
// public void load(Reader reader):把文件裏的數據讀取到集合中
// 注意:這個文件的數據必須是鍵值對形式
Reader r = new FileReader("prop.txt");
prop.load(r);
r.close();
System.out.println("prop:" + prop);
}
執行打開name.txt文件
18.推斷文件裏是否有指定的鍵假設有就改動值的案例
我有一個文本文件(user.txt),我知道數據是鍵值對形式的,但是不知道內容是什麼。
請寫一個程序推斷是否有「lisi」這種鍵存在,假設有就改變事實上爲」100」
分析:
A:把文件裏的數據載入到集合中
B:遍歷集合,獲取獲得每一個鍵
C:推斷鍵是否有爲"lisi"的。假設有就改動其值爲"100"
D:把集合中的數據又一次存儲到文件裏
========================================
public static void main(String[] args) throws IOException {
// 把文件裏的數據載入到集合中
Properties prop = new Properties();
Reader r = new FileReader("user.txt");
prop.load(r);
r.close();
// 遍歷集合,獲取獲得每一個鍵
Set<String> set = prop.stringPropertyNames();
for (String key : set) {
// 推斷鍵是否有爲"lisi"的,假設有就改動其值爲"100"
if ("lisi".equals(key)) {
prop.setProperty(key, "100");
break;
}
}
// 把集合中的數據又一次存儲到文件裏
Writer w = new FileWriter("user.txt");
prop.store(w, null);//這裏設爲null,不用附加東西了
w.close();
}
=============================================
user.txt
執行後
19.怎樣讓猜數字小遊戲僅僅能玩5次案例
我有一個猜數字小遊戲的程序,請寫一個程序實現在測試類中僅僅能用5次,超過5次提示:遊戲試玩已結束。請付費。
初始化:手動建一個文件保存玩遊戲的次數(不需要寫代碼建立文件)
public static void main(String[] args) throws IOException {
// 讀取某個地方的數據。假設次數不大於5,可以繼續玩。不然就提示"遊戲試玩已結束。請付費。
// 把數據載入到集合中
Properties prop = new Properties();
Reader r = new FileReader("count.txt");
prop.load(r);
r.close();//別忘記關閉流
// 我本身的程序,我固然知道里面的鍵是誰
String value = prop.getProperty("count");
int number = Integer.parseInt(value);//String轉換爲int
if (number > 5) {
System.out.println("遊戲試玩已結束,請付費。");
System.exit(0);//別漏了這一步退出!!
} else {
number++;
prop.setProperty("count", String.valueOf(number));//int轉爲String
Writer w = new FileWriter("count.txt");
prop.store(w, null);
w.close();//別忘記關閉流
GuessNumber.start();//這個猜數字的小遊戲代碼省略
}
}
注意幾個問題:別忘記關閉流。注意字符串與Integer的轉換.別漏了 System.exit(0)
==================================================
20.NIO的介紹和JDK7下NIO的一個案例
NIO:就是New IO
nio包在JDK4出現,提供了IO流的操做效率。但是眼下還不是大範圍的使用。
JDK7的以後的nio:
Path:路徑
Paths:有一個靜態方法返回一個路徑
public static Path get(URI uri)//返回值爲Path
Files:提供了靜態方法供咱們使用
public static long copy(Path source,OutputStream out):拷貝文件
public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)//後面那個可變參數就忽略不理,僅僅接受3個參數
===================================================
下面爲課後閱讀資料
1:JDK4新IO要了解的類(本身看)
Buffer(緩衝),Channer(通道)
2:JDK7要了解的新IO類
Path:與平臺無關的路徑。
Paths:包括了返回Path的靜態方法。
public static Path get(URI uri):依據給定的URI來肯定文件路徑。
Files:操做文件的工具類。提供了大量的方法,簡單瞭解例如如下方法
public static long copy(Path source, OutputStream out) :拷貝文件
public static Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options):
把集合的數據寫到文件。
//拷貝文件
Files.copy(Paths.get("Demo.java"), newFileOutputStream("Copy.Java"));
//把集合中的數據寫到文件
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
Files.write(Paths.get("list.txt"), list, Charset.forName("gbk"));
=================================================================================================
注意:ArrayList實現了Iterable接口
所以Iterable<?
extends CharSequence> lines相應的參數可以是ArrayList的對象
先測試copy功能
而後測試write功能
public static void main(String[] args) throws IOException {
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
}
====================================================
下面是本身寫的代碼
Charset.forName("GBK")是設置編碼的
===========
源
執行後
執行後
===================================================
day22 筆記補充
登陸註冊IO版本號案例(掌握)
要求,對着寫一遍。
寫的順序參考:
cn.itcast.pojo User
cn.itcast.dao UserDao
cn.itcast.dao.impl UserDaoImpl(實現可以是集合版或者IO版)
cn.itcast.game GuessNumber
cn.itcast.test UserTest
===============================================
內存操做流(理解)
(1)有些時候咱們操做完成後,未必需要產生一個文件。就可以使用內存操做流。
(2)三種
A:ByteArrayInputStream,ByteArrayOutputStream
B:CharArrayReader,CharArrayWriter
C:StringReader,StringWriter
===============================================
打印流(掌握)
(1)字節打印流。字符打印流
(2)特色:
A:僅僅操做目的地,不操做數據源
B:可以操做隨意類型的數據
C:假設啓用了本身主動刷新。在調用println()方法的時候,能夠換行並刷新
D:可以直接操做文件
看API,假設其構造方法能夠同一時候接收File和String類型的參數,通常都是能夠直接操做文件的
(3)複製文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
String line = null;
while((line=br.readLine())!=null) {
pw.println(line);
}
pw.close();
br.close();
===============================================
5:標準輸入輸出流(理解)
(1)System類如下有這種兩個字段
in 標準輸入流
out 標準輸出流
(2)三種鍵盤錄入方式
A:main方法的args接收參數
B:System.in經過BufferedReader進行包裝
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
C:Scanner
Scanner sc = new Scanner(System.in);
(3)輸出語句的原理和怎樣使用字符流輸出數據
A:原理
System.out.println("helloworld");
PrintStream ps = System.out;//PrintStream 屬於字節流
ps.println("helloworld");
B:把System.out用字符緩衝流包裝一下使用
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
============================================================
序列化流(理解)
(1)可以把對象寫入文本文件或者在網絡中傳輸
讓被序列化的對象所屬類實現序列化接口。
該接口是一個標記接口。沒有功能需要實現。
(3)注意問題:
怎樣解決該問題呢?
在類文件裏,給出一個固定的序列化id值。
而且,這樣也可以解決黃色警告線問題
(4)面試題:
怎樣實現序列化?
什麼是反序列化?
========================================================
NIO(瞭解)
(1)JDK4出現的NIO,對曾經的IO操做進行了優化,提供了效率。但是大部分咱們看到的仍是曾經的IO
(2)JDK7的NIO的使用
Path:路徑
Paths:經過靜態方法返回一個路徑
Files:提供了常見的功能
複製文本文件
把集合中的數據寫到文本文件
=============================================================