之前學習Java_SE時候對於Java中IO這一塊簡略看,之後看Java_Web時候總會用到一些流,所以今天查查資料瀏覽衆多高人博客,整理了一番,希望大家多給意見
package cn.iotest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.SequenceInputStream;
import java.io.Writer;
import cn.iotest.User;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
public class Demo1 {
// File類相關操作
/**
* 創建一個新文件,boolean file.createNewFile() 運行結果爲true
*
* @throws IOException
*/
@Test
public void test1() throws IOException {
String filename = "D:/newfile.txt";
File file = new File(filename);
System.out.println(file.createNewFile());
}
/**
* File中的兩個常量File.pathSeparator,File.separator 下例結果爲 ; \
*/
@Test
public void test2() {
System.out.println(File.pathSeparator);
System.out.println(File.separator);
}
/**
* 保持代碼健壯,因爲在Windows下分隔符是\,但是在Linux中就不一定了,所以用靜態常量最安全 下例結果也爲true
* 再提一句,有可能有些朋友對'\'和'/'迷糊的,其實'\'和'/'是一個意思,電腦都能讀懂,
* 但是單個'\'是轉義字符的意思,所以用'\'時需要打兩個,也就是'\\' "D:/new.txt" 等同於 "D:\\new.txt"
*
* @throws IOException
*/
@Test
public void test3() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
System.out.println(file.getName() + "\n" + file.toString() + "\n"
+ file.getPath());
}
/**
* 刪除一個文件:file.exists(),file.delete() 先判斷存不存在,存在再刪除 下例結果爲true
*/
@Test
public void test4() {
String filename = "D:" + File.separator + "newfile.txt";
File file = new File(filename);
if (file.exists())
System.out.println(file.delete());
}
/**
* 創建一個文件夾file.isDirectory(),file.mkdir() 下例結果爲true
*/
@Test
public void test5() {
String filename = "D:" + File.separator + "newfile";
File file = new File(filename);
if (!file.isDirectory()) {
System.out.println(file.mkdir());
}
}
/**
* 列出指定目錄的所有文件(文件名形式) 結果爲 JTattoo.jar libquaqua.jnilib libquaqua64.jnilib
* quaqua.jar
*/
@Test
public void test6() {
String filename = "D:" + File.separator + "lookandfeel";
File file = new File(filename);
if (file.isDirectory()) {
String[] list = file.list();
for (String i : list) {
System.out.println(i);
}
}
}
/**
* 列出指定目錄的所有文件(包括隱藏文件,用路徑形式)file.listFiles() D:\lookandfeel\JTattoo.jar
* D:\lookandfeel\libquaqua.jnilib D:\lookandfeel\libquaqua64.jnilib
* D:\lookandfeel\quaqua.jar 這裏直接在控制檯輸出對象其實是默認調用了對象的toString方法,而且該方法也已經被 重寫了
*/
@Test
public void test7() {
String filename = "D:" + File.separator + "lookandfeel";
File file = new File(filename);
if (file.isDirectory()) {
File[] list = file.listFiles();
for (File i : list) {
System.out.println(i);
}
}
}
/**
* 使用RandomAccessFile寫入文件 此時打開new.txt,結果是亂碼。用處再議
*
* @throws IOException
*/
@Test
public void test8() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.write(12);
raf.writeBoolean(true);
raf.writeFloat(12.3f);
}
// 字節流
/**
* 向文件寫入字符串out.write(bytes) 字符轉字節,再輸出到文件中
*
* @throws IOException
*
*/
@Test
public void test9() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
OutputStream out = new FileOutputStream(file);
String word = "寫入的話";
byte[] bytes = word.getBytes();
out.write(bytes);
out.close();
}
/**
* 添加新內容 new FileOutputStream(file,true)表示爲追加,而不是重寫
*/
@Test
public void test10() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
OutputStream out = new FileOutputStream(file, true);
String word = "寫入";
byte[] bytes = word.getBytes();
for (int i = 0; i < bytes.length; i++) {
out.write(bytes[i]);
}
out.close();
}
/**
* 讀取文件內容 IOUtils爲commons-io的一個jar包,其中IOUtils.toByteArray(in)直接返回讀取數據的
* byte數組 輸出結果爲“寫入的話寫入”
*
* @throws IOException
*/
@Test
public void test11() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
InputStream in = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(in);
in.close();
System.out.println(new String(bytes));
}
// 字符流
/**
* 字符流和字節流在讀寫上面唯一的區別是一個是讀寫char,一個是讀寫byte
*
* 還有一點,字節流不通過緩衝區操作文件,字符流通過緩衝區操作文件 可以試一下二者在寫入信息時都不執行close()操作,結果是字節流有效,字符流無效
* 但刷新一下緩衝區一樣有效
*
* @throws IOException
*/
@Test
public void test12() throws IOException {
String fileName = "D:" + File.separator + "new.txt";
File f = new File(fileName);
char[] ch = new char[100];
Reader read = new FileReader(f);
int count = read.read(ch);
read.close();
System.out.println("讀入的長度爲:" + count);
System.out.println("內容爲" + new String(ch, 0, count));
}
// 字符流轉化爲字節流
// 主要介紹OutputStreamWriter和InputStreamReader
/**
* 字符輸出流轉化爲字節輸出流 可能不好理解,簡單來說就是你存的是字符,但是最後轉化爲了字節存儲
* 字節送給writer,然後writer再通過轉換將數據轉爲字節傳給指定outputStream
*
* 最後結果爲hello,看清楚,我們輸入的是String也就是char[]
*
* @throws IOException
*/
@Test
public void test13() throws IOException {
Writer writer = new OutputStreamWriter(new FileOutputStream("D:"
+ File.separator + "test13.txt"));
writer.write("hello");
writer.close();
}
/**
* InputStreamReader無非是用將數據以字節流讀入,最後用char[]接收,不浪費篇幅了
*/
/**
* 博主最近學習時接觸到outputStreamWriter類,給大家說一下,覺得有啓發的看官就收着 沒啥用就跳過
* 將該類用於SAX解析器解析XML文檔進行XML回寫的相關操作
* XML回寫用的是XMLWriter類,需求的是一個Writer子類,但是相關類是不提供編碼設置的,
* 也就是說必須使用指定默認編碼,這不扯淡麼!這時就要用outputStreamWriter類來設置
* 編碼了,就是帶編碼格式的outputStreamWriter構造器
*/
// @Test
// public void test14(Object user){
// //省去部分代碼,此處沒導dom4j的jar包,沒找到相關類而已
// XMLWriter writer;
// try {
// /**
// * 將輸入的信息以utf-8的編碼方式轉化爲字節輸出流保存起來,format是一個格式規範器
// */
// writer = new XMLWriter(new OutputStreamWriter(
// new FileOutputStream(path),"UTF-8"), format);
// writer.write(doc );//doc爲Document文檔對象
//
//
// }
/**
* PrintStream(裝飾流)
* 打印流最主要的是區別,打印流可以選擇控制檯也可以選擇文件作爲目的地。 例如:System.out.println就是把目的地選擇爲了控制檯。
* 當然如果輸出到文件,如果使用打印流則是將打印流指定到輸出流管道, 實現輸出的還是輸出流。因此,如果目的地是文件,選擇輸出流較好。
*
* 結果爲: append13 c
*
* @throws IOException
*/
@Test
public void test14() throws IOException {
PrintStream ps = new PrintStream(new FileOutputStream("D:"
+ File.separator + "test14.txt"));
ps.append("append");
byte[] bytes = "write".getBytes();
ps.println(13);
ps.print('c');
}
/**
* 使用OutputStream向屏幕輸出數據 只需要構造OutputStream output = System.out; 其他操作相同即可
*
* @throws IOException
*/
/**
* BufferedReader,只能接受字符流的緩衝區,將System.in轉換爲字符流(裝飾流)
*
* BufferedReader buf = new BufferedReader( new
* InputStreamReader(System.in));
*/
@Test
public void test15() throws IOException {
BufferedReader buf = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("請輸入你要輸出的信息");
String words = buf.readLine();
System.out.println("您輸出的信息是" + words);
buf.close();
}
/**
* 合併流 SequenceInputStream(沒有SequenceOutputStream)
* 將兩個字節輸入流按前後順序合併爲一個字節輸入流,其他操作可以對合並流進行(裝飾流)
* @throws IOException
*/
@Test
public void test16() throws IOException{
InputStream in1 = new FileInputStream("D:"+ File.separator + "test16_1.txt");
InputStream in2 = new FileInputStream("D:"+ File.separator + "test16_2.txt");
OutputStream out = new FileOutputStream("D:"+ File.separator + "test16_out.txt");
SequenceInputStream seq = new SequenceInputStream(in1, in2);
byte[] temp = null;
int count;
//讀,IOUtils.toByteArray()是封裝好的將輸入流的數據轉化爲byte數組
temp = IOUtils.toByteArray(seq);
//寫
out.write(temp);
}
/**
* 最後說一下序列化與反序列化,一個類想要能被序列化,首先要實現Serializable接口
* 這個接口裏面沒有任何方法,只要聲明,就說明這個類能夠被序列化,具體什麼是序列化
* 先來看看ObjectInputStream和ObjectOutputStream兩個類(裝飾流)
* ObjectOutputStream用來將對象轉化爲二進制數據進行存儲
* ObjectInputStream用來將數據進行轉化爲對象
*
* 下例輸出結果爲
* User [username=張三, age=21]
*
*
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
@Test
public void test17() throws FileNotFoundException, IOException, ClassNotFoundException{
File file = new File("D:"+ File.separator + "test17.txt");
ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream(file));
objout.writeObject(new User("張三",21));//這時寫進的是二進制數據
ObjectInputStream objin = new ObjectInputStream(new FileInputStream(file));
Object user = objin.readObject();//寫到這裏時記得導入相應對象的包,由於返回Object類型,他是不會提醒你的
//至於這一塊JVM是怎麼認出讀出的數據是User對象的,可能序列化時候有唯一標識吧,這裏我也不清楚它怎麼實現的
System.out.println(user.toString());
}
/**
* 再來簡略談談Externalizable接口,Serializable接口默認實現全部屬性序列化
* 注意!序列化時只有屬性被序列化
* 而繼承Externalizable接口則可以由我們自己定實現哪些屬性被序列化
* 並且這個類中必須要有一個無參的構造函數,如果沒有的話,在構造的時候會產生異常,
* 這是因爲在反序列話的時候會默認調用無參的構造函數。
*
* 該接口有兩個方法需要實現,一個就是序列化,一個就是反序列化
*
*/
/**
* 對於Externalizable接口,實現太過麻煩,對於不想被序列化的屬性
* 我們只需要加上關鍵字transient即可
* transient關鍵字的意義簡單說就是被修飾的成員不會被本地化
* 例如賬號的密碼可以用這個修飾
*/
/**
* IO流簡單說道這裏,有一些較偏的我也沒有整理(博主也起步學習不久)。越努力,越幸運
<span style="white-space:pre"> </span>
}