摘要:JAVA IO
IO流用來處理設備之間的資料傳輸
Java對資料的操作是通過流的方式
Java用於操作流的物件都在IO包中
流分為兩種:位元組流與字元流
位元組流抽象類:InputStream,OutputStream
字元流抽象類:Reader,Writer
由這四個類衍生出來的子類名稱都是以其父類名作為子類名的尾碼。
如:InputStream的子類FileInputStream。
如:Reader的子類FileReader。
創建流物件,建立資料存放檔
FileWriter fw = new FileWriter(“Test.txt”); //如果已有相同名稱文件,則會被覆蓋
調用流物件的寫入方法,將資料寫入流
fw.write(“text”); //寫入資料到流緩衝中
刷新流的緩衝,寫入到目的檔案內,流可繼續使用
fw.flush();
關閉流資源,並將流中的資料清空到檔中,流不可繼續使用
fw.close();
ex:
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args)throws IOException{
FileWriter fw = new FileWriter("123.txt");
fw.write("123");
fw.flush();
fw.close();
}
}
導入IO包中的類
進行IO異常處理
在finally中對流進行關閉
有了垃圾回收機制為什麼還要調用close方法進行關閉。
建立一個流物件,將已存在的一個檔載入進流。
FileReader fr = new FileReader(“Test.txt”);
創建一個臨時存放資料的陣列。
char[] ch = new char[1024];
調用流物件的讀取方法將流中的資料讀入到陣列中。
fr.read(ch);
ex:
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args){
FileWriter fw = null;
try{
fw = new FileWriter("d:\\Test.txt");
fw.write("text");
}catch (IOException e){
System.out.println(e.toString());
}finally{
try{
fw.flush();
fw.close();
}catch (IOException e){
System.out.println(e.toString());
}
}
}
}
建構子:
FileWriter(String filename)
FileWriter(String filename, boolean append)
若append為true則表示不覆蓋,附加在檔案內容後
若要輸入換行,則要為\r\n (windos環境下)
讀取:
FileReader fr = null;
try {
fr = new FileReader("C:\\Test.txt");
char[] buf = new char[1024];
int len = 0;
while ((len = fr.read(buf)) != -1) { //讀完時傳回-1
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
System.out.println("read-Exception :" + e.toString());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("close-Exception :" + e.toString());
}
}
}
路徑需注意:
"C:\\eclipse_project\\Object_test\\Test.txt"
Reader方法:
public int read() 讀出字元,返回int型,讀到結尾傳回-1
public int read(char[] buf) 將字元讀入陣列中,讀到結尾傳回-1
複製檔案:
public class Main {
public static void main(String[] args)throws IOException{
copy();
}
public static void copy() throws IOException{
FileWriter fw = new FileWriter("Cpoy.txt");
FileReader fr = new FileReader("路徑");
int ch = 0;
while((ch = fr.read()) != -1){
fw.write(ch);
}
fw.close();
fr.close();
}
}
加入緩衝copy
public class Main {
public static void main(String[] args)throws IOException{
copy();
}
public static void copy(){
FileWriter fw = null;
FileReader fr = null;
try{
fw = new FileWriter("Copy2.txt");
fr = new FileReader("c:\\Copy.txt");
char[] buf = new char[1024];
int len = 0;
while((len = fr.read(buf)) != -1){
fw.write(buf, 0, len);
}
}catch(IOException e){
throw new RuntimeException("讀取失敗");
}finally{
if(fr != null){
try{
fr.close();
}catch(IOException e){
}
}
if(fw != null){
try{
fw.close();
}catch(IOException e){
}
}
}
}
}
緩衝區的出現提高了對資料的讀寫效率。
在創建緩衝區之前必須要先有流才可以使用,在流的基礎上對流的功能進行了增強
BufferedWriter、BufferedReader類別
public class Main {
public static void main(String[] args)throws IOException{
FileWriter fw = new FileWriter("Test.txt");
BufferedWriter bufw = new BufferedWriter(fw);
bufw.write("ABCDE"); //緩衝區一定要刷新
bufw.newLine();
bufw.write("FGHIJK");
bufw.flush();
bufw.close();
FileReader fr = new FileReader("C:\\Test.txt");
BufferedReader bufr = new BufferedReader(fr);
String data = null;
while((data = bufr.readLine()) != null){
System.out.println("data = " + data);
}
bufr.close();
}
}
newLine()跨平台的換行方法
readLine()一次讀取一行,不讀換行符號!
LineNumberReader類別可獲取文件中的行號
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class Main {
public static void main(String[] args)throws IOException{
FileReader fr = new FileReader("C:\\Test.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
while((line = lnr.readLine()) != null){
System.out.println(lnr.getLineNumber() + ":" + line);
}
lnr.close();
}
}
位元組流
不僅可以操作位元組 ,還可以操作其他媒體檔,同樣是提高了位元組流的讀寫效率。
InputStreamReader,OutputStreamWriter為抽象類,透過操過其子類來使用
public class Main {
public static void main(String[] args)throws IOException{
writeFile();
readFile();
readFile_1();
}
public static void writeFile()throws IOException{
FileOutputStream fos = new FileOutputStream("Test.txt");
fos.write("123456789".getBytes());
fos.close();
}
public static void readFile()throws IOException{
FileInputStream fis = new FileInputStream("Test.txt");
int ch = 0;
while((ch = fis.read()) != -1){
System.out.println((char)ch);
}
fis.close();
}
public static void readFile_1()throws IOException{
FileInputStream fis = new FileInputStream("Test.txt");
int num = fis.available(); //計算字元數 包含\r \n
System.out.println(num);
fis.close();
}
}
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf)) != -1){ //若1024不夠會在循環讀
…
}
將上面修改如下
byte[] buf = new byte[fis.available()];
定義一個剛剛好的緩衝區,可以不用再循環讀,可增加效率
複製一張圖片
- 用字元流讀取一張圖片
- 用字元寫入流物件產生一張圖片,用於儲存圖片數據
- 循環讀寫
- 關閉流
public class Main {
public static void main(String[] args){
FileOutputStream fos = null;
FileInputStream fis = null;
try{
fos = new FileOutputStream("c:\\321.jpg");
fis = new FileInputStream("c:\\123.jpg");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf)) != -1){
fos.write(buf, 0, len);
}
}catch(IOException e){
throw new RuntimeException("複製文件失敗");
}finally{
try{
if(fis != null)
fis.close();
}catch(IOException e){
throw new RuntimeException("讀取關閉失敗");
}
try{
if(fos != null)
fos.close();
}catch(IOException e){
throw new RuntimeException("寫入關閉失敗");
}
}
}
}
複製mp3文件
public class Main {
public static void main(String[] args)throws IOException{
long start = System.currentTimeMillis();
copy_1();
long end = System.currentTimeMillis();
System.out.println((end - start) + "毫秒");
}
public static void copy_1() throws IOException{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\123.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\321.mp3"));
int by = 0;
while((by = bufis.read()) != -1){
bufos.write(by);
}
bufis.close();
bufos.close();
}
}
讀取鍵盤輸入
System.in的類型是InputStream預設輸入裝置是鍵盤、FileStream硬碟、ArrayStream記憶體
System.out的類型是PrintStream輸出設備是螢幕、FileStream硬碟、ArrayStream記憶體
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args)throws IOException{
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true){
int ch = in.read();
if(ch == '\r')
continue;
if(ch == '\n'){
String s = sb.toString();
if("over".equals(s)) //輸入over結束
break;
System.out.println(s.toUpperCase());
sb.delete(0, sb.length()); //緩衝區清空
}
else{
sb.append((char)ch);
}
}
}
}
改良,使用轉換流操作,目的是要使用到readLine()方法來簡化
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args)throws IOException{
InputStream in = System.in;
//將字節轉成字符流物件
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
InputStreamReader是位元組串流通向字元串流的橋梁
最後改良
public class Main {
public static void main(String[] args)throws IOException{
//InputStream in = System.in;
//InputStreamReader isr = new InputStreamReader(in); //將位元組轉成字元流物件
//BufferedReader bufr = new BufferedReader(isr);
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//OutputStream out = System.out;
//OutputStreamWriter osw = new OutputStreamWriter(out);
//BufferedWriter bufw = new BufferedWriter(osw);
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
鍵盤輸入螢幕輸出
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
將鍵盤輸入內容輸出到文件中
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Test.txt")));
將文件內容輸出到console中
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream("Test.txt")));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
了解源和目的
源: 輸入流 InputStream 、Reader
目的: 輸出流 OuputStream、Writer
操作的數據是否是純文本
是 字符流 Writer、Reader
不是 字節流 InputStream、OutputStream
設備區分
源設備: 記憶體、硬碟、鍵盤
目的設備: 記憶體、硬碟、console
將輸出訊息儲存到文件中,日誌製作
轉換流的應用位元組流中的資料都是字元時,轉成字元流操作 更高效。
常式:標準輸入輸出
System類中的欄位:in,out。
它們各代表了系統標準的輸入和輸出設備。
.
是 OutputStream的子類FilterOutputStream 的子類.
例:獲取鍵盤錄入資料,然後將資料流程向顯示器,那麼顯示器就是目 的地。
通過System類的setIn,setOut方法對預設設備進行改變。
System.setIn(new FileInputStream(“1.txt”));//將源改成文件1.txt。
System.setOut(new FileOutputStream(“2.txt”));//將目的改成檔2.txt
系統訊息
import java.io.PrintStream;
import java.util.Properties;
public class Main {
public static void main(String[] args) throws Exception{
Properties prop = new Properties();
//Systme.out.println(prop); 這一行是產生到console上
prop.list(new PrintStream("sysinfo.txt")); //輸出系統訊息到sysinfo.txt檔
}
}
File類別:
用來將文件或文件夾封裝成物件,方便對文件與文件夾的屬性訊息進行操作,File物件可以作為參數傳遞給流的建構子
public class Main {
public static void main(String[] args) throws Exception{
create();
}
public static void create()throws IOException{
File f = new File("a.txt");
//創建文件,如果文件已經存在,則不創建,返回false
//和輸出流不一樣,輸出流創建文件,一旦存在就會覆蓋
sop("create: " + f.createNewFile());
}
public static void sop(Object obj){
System.out.println(obj);
}
}
過濾副檔名來列出檔案
class Hello{
public static void main(String[] args)throws Exception{
File dir = new File("d:\\");
//匿名內部類
String[] arr = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//依dir的副檔名來判斷
return name.endsWith(".rar");
}
});
System.out.println("len: " + arr.length);
for(String name: arr){
System.out.println(name);
}
}
}
顯示某一目錄下所有檔案,包含目錄中的子檔案,使用遞迴呼叫
class Hello{
public static void main(String[] args)throws Exception{
File dir = new File("d:\\");
showDir(dir);
}
public static void showDir(File dir){
File[] files = dir.listFiles();
for(int x = 0; x < files.length; x++){
if(files[x].isDirectory())
showDir(files[x]);
else {
System.out.println(files[x]);
}
}
}
}
改良: 加入層級顯示
class Hello{
public static void main(String[] args)throws Exception{
File dir = new File("d:\\");
showDir(dir, 0);
}
public static void showDir(File dir, int level){
System.out.println(getLevel(level) + dir.getName());
level++;
File[] files = dir.listFiles();
for(int x = 0; x < files.length; x++){
if(files[x].isDirectory())
showDir(files[x], level);
else {
System.out.println(getLevel(level) + files[x]);
}
}
}
public static String getLevel(int level){
StringBuilder sb = new StringBuilder();
for(int x = 0; x < level; x++){
sb.append("|--");
}
return sb.toString();
}
}
刪除一個帶內容的目錄,由裡面往外面刪除
class Hello{
public static void main(String[] args)throws Exception{
File dir = new File("d:\\test");
removeDir(dir);
}
public static void removeDir(File dir){
File[] files = dir.listFiles();
for(int x = 0; x < files.length; x++){
if(files[x].isDirectory())
removeDir(files[x]);
else {
System.out.println(files[x].toString() + ":-file-:" + files[x].delete());
}
}
System.out.println(dir + "::dir::" + dir.delete());
}
}
由某一路徑下存儲所有檔案
class Hello{
public static void main(String[] args)throws IOException{
File dir = new File("d:\\123");
List list = new ArrayList();
fileToList(dir, list);
File file = new File(dir, "123.txt");
writeToFile(list, file.toString());
}
public static void fileToList(File dir, List list){
File[] files = dir.listFiles();
for(File file: files){
if(file.isDirectory()){
fileToList(file, list);
}else{
if(file.getName().endsWith("java")){
list.add(file);
}
}
}
}
//將路徑下所有符合java檔案類型文件存入到123.txt檔中, 包含路徑+檔名
public static void writeToFile(List list, String javaListFile)throws IOException{
BufferedWriter bufw = null;
try{
bufw = new BufferedWriter(new FileWriter(javaListFile));
for(File f: list){
String path = f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
}catch(IOException e){
throw e;
}finally{
try{
if(bufw != null)
bufw.close();
}catch (IOException e) {
throw e;
}
}
}
}
常用IO類別:
管道流
PipedInputStream和PipedOutputStream輸入輸出可以直接進行連接,通過結合執行緒使用。
列印流
PrintWriter與PrintStream可以直接操作輸入流和檔。
序列流
SequenceInputStream對多個流進行合併。
操作物件
ObjectInputStream與ObjectOutputStream被操作的物件需要實現Serializable (標記介面);
操作基底資料型別
DataInputStream與DataOutputStream
DataInputStream與DataOutputStream
操作位元組陣列
ByteArrayInputStream與ByteArrayOutputStream
操作字元陣列
CharArrayReader與CharArrayWrite
操作字串
StringReader 與StringWriter
字元流的出現為了方便操作字元。
更重要是的加入了編碼轉換。
通過子類轉換流來完成。InputStreamReader OutputStreamWriter
在兩個物件進行構造的時候可以加入字元集。
電腦只能識別二進位資料,早期由來是電信號。
為了方便應用電腦,讓它可以識別各個國家的文字。
就將各個國家的文字用數位來表示,並一 一對應,形成一張表。
這就是編碼表
可以將字元以指定編碼格式存儲
指定編碼表的動作由構造函數完成
編碼: 字串 ----> 位元組陣列
解碼:位元組陣列 -----> 字串
Properties類別
//Properties是hashtable子類 具備map集合特點 存儲鍵值對
//用於鍵值對形式的配置文件 數據需要有固定格式: 鍵 = 值
class Hello{
public static void main(String[] args){
setAndGet();
}
public static void setAndGet(){
Properties prop = new Properties();
prop.setProperty("kent", "30");
prop.setProperty("lance", "15");
//String value = prop.getProperty("kent");
//System.out.println(value);
Set names = prop.stringPropertyNames();
for(String s: names){
System.out.println(s + ":" + prop.getProperty(s));
//lance:15 kent:30
}
}
}
讀取txt存入Properties中
class Main{
public static void main(String[] args)throws IOException{
setAndGet();
}
/**讀入txt文件中鍵值進行操作
* 1. 使用流與txt關聯
* 2. 讀取一行數據 將該行數據用 "=" 切割
* 3. 等號左邊為鍵 右邊為值 存入properties中*/
public static void setAndGet() throws IOException{
String path = "C:\\keyValueTest.txt";
BufferedReader bufr = new BufferedReader(new FileReader(path));
Properties p = new Properties();
String line = null;
while((line = bufr.readLine()) != null){
String[] arr = line.split("=");
p.setProperty(arr[0], arr[1]);
System.out.println(line);
}
bufr.close();
System.out.println(p);
}
}
使用Properties類的load方法,載入檔案並修改後存入檔案
class Main{
public static void main(String[] args)throws IOException{
setAndGet();
}
public static void setAndGet() throws IOException{
String path = "C:\\keyValueTest.txt";
FileInputStream fis = new FileInputStream(path);
Properties p = new Properties();
p.load(fis);
//p.list(System.out);//-- listing properties --//lance=30, kent=25, laker=50
p.setProperty("laker", "111");//修改
FileOutputStream fos = new FileOutputStream(path);
p.store(fos , "TEST");
System.out.println(p);
fos.close();
fis.close();
}
}
//用於紀錄應用程式運行次數
//若使用次數已到,顯示註冊提示
//程序結束後會自動存值 下一次啟動時也要保存上次的値
class Main{
public static void main(String[] args)throws IOException{
Properties p = new Properties();
File file = new File("c:\\propertiesDemo.ini");
if(!file.exists()){
file.createNewFile();//不存在則創造新檔案
}
FileInputStream fis = new FileInputStream(file);
p.load(fis);
int count = 0;
String value = p.getProperty("time");
if(value != null){
count = Integer.parseInt(value);
if(count >= 5){
System.out.println("使用次數超過");
return ;
}
}
count++;
p.setProperty("time", count + "");
FileOutputStream fos = new FileOutputStream(file);
p.store(fos, "");
fos.close();
fis.close();
}
}
PrintStream 字串
提供了列印方法 可以將各種數據類型的數據輸出
建構子可接收的參數類型
1. file物件 File
2. 字串路徑 String
3. 字串輸出流 OutputStream
PrintWriter 字元
建構子可接收的參數類型
1. file物件 File
2. 字串路徑 String
3. 字串輸出流 OutputStream
4. 字元輸出流 Write
//輸入字母 轉大寫
class Main{
public static void main(String[] args) throws Exception{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String line = null;
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
out.println(line.toUpperCase());
out.flush();
}
out.close();
bufr.close();
}
}
SequenceInputStream
將多個檔案流合併為一個再輸出
class Hello{
public static void main(String[] args) throws IOException{
Vector v = new Vector();
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
Enumeration en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\4.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len = sis.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.close();
sis.close();
}
}
切割檔案後,再合併
class Hello{
public static void main(String[] args) throws IOException{
splitFile();
merge();
}
public static void splitFile() throws IOException{
FileInputStream fis = new FileInputStream("G:\\1.MP3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len = fis.read(buf)) != -1){
fos = new FileOutputStream("G:\\spilt\\"+ (count++) +".part");
fos.write(buf, 0, len);
fos.close();
}
fis.close();
}
public static void merge() throws IOException{
ArrayList al = new ArrayList();
for(int x = 1; x < 5; x++){
al.add(new FileInputStream("G:\\spilt\\"+ x +".part"));
}
final Iterator it = al.iterator();
Enumeration en = new Enumeration() {
public boolean hasMoreElements(){
return it.hasNext();
}
public FileInputStream nextElement(){
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("G:\\spilt\\0.MP3");
byte[] buf = new byte[1024];
int len = 0;
while((len = sis.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.close();
sis.close();
}
}
ObjectInputStram,ObjectOutputStream
操作物件的流,需實現Serializable
class Hello{
public static void main(String[] args)throws IOException, ClassNotFoundException{
writeObj();
readObj();
}
public static void writeObj()throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("G:\\obj.txt"));
oos.writeObject(new Person("kent", 20));
oos.close();
}
public static void readObj()throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("G:\\obj.txt"));
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
class Person implements Serializable{
public static final long serialVersionUID = 42L;
String name;
int age;
Person(String name, int age){
this.name = name;
this.age = age;
}
public String toString(){
return name + ":" + age;
}
}
管道流
PipedInputStream、PipedOutputStream
輸入輸出可以直接進行連接,通過結合執行緒使用
class Hello{
public static void main(String[] args)throws IOException{
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
class Read implements Runnable{
private PipedInputStream in;
Read(PipedInputStream in){
this.in = in;
}
public void run(){
try{
byte[] buf = new byte[1024];
int len = in.read(buf);
String s = new String(buf, 0, len);
System.out.println(s);
in.close();
}catch(IOException e){
throw new RuntimeException("讀取失敗");
}
}
}
class Write implements Runnable{
private PipedOutputStream out;
Write(PipedOutputStream out){
this.out = out;
}
public void run(){
try{
out.write("輸出此內容!".getBytes());
out.close();
}catch(IOException e){
throw new RuntimeException("讀取失敗");
}
}
}
RandomAccessFile
隨機訪問文件,自身具備讀寫
該類別不算是IO體系中子類而是直接繼承自Object
但是他是IO包中成員,因為他具備讀與寫功能,內部封裝了一個陣列,通過指標對數組的元素進行操作,可以通過getFilePointer獲取指標位置,同時可以通過seek改變指標位置
能完成讀寫的原理就是內部封裝了位元組流
通過建構子可以看出,該類只能操作文件,而且操作方式還有mode: 只讀(r)、讀寫(rw)
若該物件的建構子要操作的文件不存在,會自動創建,如果存在則不會覆蓋
模式為r,不會創建文件,會去讀取一個已存在文件,如果該文件不存在,則會出現異常
模式為rw,操作的文件不存在,會自動創建,如果存在則不會覆蓋
class Main{
public static void main(String[] args) throws Exception{
writeFile();
read();
}
public static void writeFile() throws Exception{
RandomAccessFile raf = new RandomAccessFile("d:\\test.txt", "rw");
raf.write("kent".getBytes());
raf.writeInt(97);
raf.write("kobe".getBytes());
raf.writeInt(97);
raf.close();
}
public static void read()throws Exception{
RandomAccessFile raf = new RandomAccessFile("d:\\test.txt", "r");
//調整物件中的指標
raf.seek(8); //跳過指定的字元數 raf.skipBytes(8);
byte[] buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name = " + name);
System.out.println("age = " + age);
raf.close();
}
}
DataInputStream、DataOutputStream
可以用於操作基本數據類型的數據流物件
class Main{
public static void main(String[] args) throws Exception{
//writeData();
//readData();
writeUTF();
readUTF();
}
public static void writeData() throws Exception{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\test.txt"));
dos.writeInt(546);
dos.writeBoolean(true);
dos.writeDouble(154.12);
dos.close();
}
public static void readData()throws Exception{
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\test.txt"));
int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println("num = " + num + ", b = " + b + ", d = " + d);
dis.close();
}
public static void writeUTF() throws Exception{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\UTF.txt"));
dos.writeUTF("測試");
}
public static void readUTF() throws Exception{
DataInputStream dis = new DataInputStream(new FileInputStream("D:\\UTF.txt"));
String s = dis.readUTF();
System.out.println(s);
}
}
操作位元組
ByteArrayInputStream與ByteArrayOutputStream
ByteArrayInputStream在建構子時,需要接收數據源,而且數據源是ㄧ個位元組陣列
ByteArrayOutputStream在建構子時,不用定義數據源目的,因為該物件中已經內部封裝了可變長度的位元組陣列
因為這兩個流物件都操作的陣列,並沒有使用系統資源,所以不用進行close關閉
class Main{
public static void main(String[] args) throws Exception{
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEF".getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by = bis.read()) != -1 ){
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
}
}
編碼表
ASCII:美國標準資訊交換碼。用一個位元組的7位元可以表示。
ISO8859-1:拉丁碼表。歐洲碼表用一個位元組的8位元表示。
GB2312:中文編碼表。
GBK:中文編碼表升級,融合了更多的中文字元。
Unicode:國際標準碼,融合了多種文字。所有文字都用兩個位元組來表示,Java語言使用的就是unicode
UTF-8:最多用三個位元組來表示一個字元。
轉換流
class Main{
public static void main(String[] args) throws Exception{
writeTest();
readTest();
}
public static void writeTest() throws Exception{
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\UTF-8.txt"), "UTF-8");
//"UTF-8" 每一个字占3Byte
osw.write("测试");
osw.close();
}
public static void readTest() throws Exception{
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\UTF-8.txt"), "UTF-8");
char[] buf = new char[30];
int len = isr.read();
String str = new String(buf, 0, len);
System.out.println(str);
isr.close();
}
}
編碼: 字串變成位元陣列
解碼: 位元陣列變成字串
//String -> byte[]; 使用 str.getBytes(charsetName);
//byte[] -> String; 使用 new String(byte[], charsetName);
class Main{
public static void main(String[] args) throws Exception{
String s = "測試";
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));//[-100, 121, -44, -121]
byte[] b2 = s.getBytes("UTF-8");
System.out.println(Arrays.toString(b2));//[-26, -72, -84, -24, -87, -90]
String s1 = new String(b1, "GBK");
System.out.println(s1);//測試
String s2 = new String(b2, "UTF-8");
System.out.println(s2);//測試
}
}
//測試(GBK)寫 ---> ??(UTF-8)讀 ----|
//測試(GBK)讀 <--- ??(UTF-8)寫 <---|
//有5個學生 3門課
//從鍵盤輸入成績(姓名 成績)
//把結果依分數高低存入"stud.txt中"
/**
* 1. 描述學生物件
* 2. 定義一個可操作學生物件的工具類
* 1. 通過獲取鍵盤輸入一行數據,並將該行中的訊息取出封裝成學生物件
* 2. 使用集合(TreeSet)
* 3. 將集合的訊息寫入到一個文件中
* */
class Main{
public static void main(String[] args) throws Exception{
Comparator cmp = Collections.reverseOrder();
Set stus = StudentInfoTool.getStudents();
StudentInfoTool.writeToFile(stus);
}
}
class Student implements Comparable{
private String name;
private int a, b, c;
private int sum;
Student(String name, int a, int b, int c){
this.name = name;
this.a = a;
this.b = b;
this.c = c;
sum = a + b + c;
}
public String getName(){
return name;
}
public int getSum(){
return sum;
}
public int hashCode(){
return name.hashCode() + sum*78;
}
public boolean equals(Object obj){
if(!(obj instanceof Student)){
throw new ClassCastException("非學生類");
}
Student s = (Student)obj;
return this.name.equals(s.name) && this.sum == s.sum;
}
public String toString(){
return "student[" + name + ", " + a + ", " + b + ", " + c+ "]";
}
public int compareTo(Student s){
int num = new Integer(this.sum).compareTo((new Integer(s.sum)));
if(num == 0)
return this.name.compareTo(s.name);
return num;
}
}
class StudentInfoTool{
public static Set getStudents() throws Exception{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
Set stus = new TreeSet();
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
String[] info = line.split(",");
Student stu = new Student(info[0], Integer.parseInt(info[1]),
Integer.parseInt(info[2]), Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
return stus;
}
public static void writeToFile(Set stus) throws IOException{
BufferedWriter bufw = new BufferedWriter(new FileWriter("D:\\stuinfo.txt"));
for(Student stu: stus){
bufw.write(stu.toString() + "\t");
bufw.write(stu.getSum() + "");
bufw.newLine();
bufw.flush();
}
}
}