簡單記事本功能實現
2018-9-8
使用IO流來實現,先了解一下流
什麼是流
流,字面意思就是流動的意思,可以理解爲數據的流動,從一個地方流動到另一個地方。所以IO也依它們的流動方向分爲了輸入流和輸出流。
- 輸入流
就是數據從磁盤“流動”到內存,—->讀取 - 輸出流
數據從內存”流動”到磁盤, —->寫入
字節輸入流 InputStream
因爲InputStream自身是一個抽象類,無法實例化,所以我們如果想要使用到輸入流就需要去創建它的子類對象。在它的實現子類中我們最常用到的就是FileInputStream。
FileInputStream(String name) ,我們可以使用它的構造方法,傳入一個抽象路徑來實現與一個文件建立關聯。建立關聯之後使用它的read方法來實現文件的讀取。它的文件讀取分爲一下幾種方式:
- int read() :一次讀取一個字節,讀到文檔末尾則返回-1。通常讀取文件內容時我們使用循環去讀取
- int read(byte[] b) : 每次讀取b.length()個字節數據,即b有多長我們一次就讀多少,每次讀取都會覆蓋數組中上次讀到的數據
還有一種方式就不多介紹了,常用就以上兩種
字節輸出流 OutputStream
同樣的OutputStream自身也是一個抽象類,我們需要使用它的子類對象FileOutputStream。
FileOutputStream(String name) :與指定抽象路徑文件關聯。建立關聯之後使用它的方法write來實現文件的寫入(磁盤)。同樣的它長用的有兩種方式:
- void write() : 一次寫入一個字節的數據,到達文檔末尾返回-1
- void write(byte[] b) : 一次寫入b長度個字節的數據,每次都會覆蓋數組中上次讀到的數據
字符輸入流 FileReader
字符輸入流,它操作的數據單位與字節流不一樣,它操作的單位是字符
FileReader(String fileName) : 與指定的抽象路徑文件建立連接,關聯之後使用read方法讀取文件
- int read() : 每次讀取一個字符長度的數據,讀到文檔末尾返回-1
- int read(char[] c) : 每次讀取c長度個字符的數據,讀到文檔末尾返回-1,每次讀取都會覆蓋數組中上次讀到的數據
字符輸出流 FileWriter
FileWriter(String fileName) :與指定抽象路徑的文件建立連接,關聯之後使用write方法實現文件內容寫入(磁盤)。當然,我這裏只是使用了最簡單的構造方法來構建,以上所有流都是還有其他的構建方式的。
- void write() : 每次寫入一個字符長度數據,寫入的時候注意要使用flush方法或者使用close方法刷新流(close方法會刷新流)
- void write(String s) : 字符輸出流特殊一點就是可以直接寫入字符串
- void write(char[] c) : 每次輸出c長度的字符數據
無論使用哪種方式寫入都要注意刷新流,否則不會有寫入效果
流的選擇
那麼,平時使用的時候要怎麼選擇呢?我們主要看要傳輸的文檔類型,如果是文本文檔最好是使用字符流,如果是多媒體文件最好使用字節流
瞭解了流之後我們就可以開始使用它們來實現一些簡單的記事本功能了。在這主要實現記事本的打開、保存、和另存功能。
思路:
- 打開:
就是從磁盤讀取文件內容,顯示到記事本文本框中 - 保存
需要判斷要保存的文件是否是新建的文件(即不是本地已有文件),如果是新建的文件則彈出保存對話框。如果不是,直接保存到源文件中 - 另存
選擇文件路徑保存
好了,直接上代碼!
Frame界面
import java.awt.TextArea;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextArea;
public class FrameDemo extends JFrame{
private TextArea texts;
private String title;
public FrameDemo() {
init();
}
private void init() {
title = "無標題";
JFrame frame = new JFrame(title);
frame.setVisible(true);
frame.setSize(600, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);//3
addJMenuBarToFrame(frame);
addTextAreaToFrame(frame);
}
private void addTextAreaToFrame(JFrame frame) {
// TODO Auto-generated method stub
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("文件(F)");
JMenu edit = new JMenu("編輯(E)");
JMenu format = new JMenu("格式(O)");
JMenu view = new JMenu("查看(V)");
JMenu help = new JMenu("幫助(H)");
//文件
JMenuItem newFile = new JMenuItem("新建(N) CTRL+N");
JMenuItem open = new JMenuItem("打開(O) CTRL+O");
JMenuItem save = new JMenuItem("保存(S) CTRL+S");
JMenuItem saveAs = new JMenuItem("另存爲(A)");
JMenuItem pageSettings = new JMenuItem("頁面設置(U)");
JMenuItem print = new JMenuItem("打印(P) CTRL+P");
JMenuItem exit = new JMenuItem("退出(E)");
file.add(newFile);
file.add(open);
//給打開文件添加監聽器
OpenActionListener oal = new OpenActionListener(frame,texts);
open.addActionListener(oal);
file.add(save);
//保存事件監聽
SaveActionListener sal = new SaveActionListener(texts, frame);
save.addActionListener(sal);
file.add(saveAs);
//添加另存監聽器
SaveAsActionListener saal = new SaveAsActionListener(frame,texts);
saveAs.addActionListener(saal);
file.addSeparator();
file.add(pageSettings);
file.add(print);
file.addSeparator();
file.add(exit);
//給退出添加時間監聽器
ExitActionListener eal = new ExitActionListener();
exit.addActionListener(eal);
menuBar.add(file);
menuBar.add(edit);
menuBar.add(format);
menuBar.add(view);
menuBar.add(help);
frame.setJMenuBar(menuBar);
}
private void addJMenuBarToFrame(JFrame frame) {
// TODO Auto-generated method stub
texts = new TextArea();
frame.add(texts);
}
}
打開功能
import java.awt.FileDialog;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream.GetField;
import javax.swing.JFrame;
public class OpenActionListener implements ActionListener {
private JFrame frame;
private TextArea textArea;
public static String realepath;
public OpenActionListener(JFrame frame,TextArea textArea) {
super();
this.frame = frame;
this.textArea = textArea;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
FileDialog fd = new FileDialog(frame,"open",FileDialog.LOAD);
//FileDialog默認不可見
fd.setVisible(true);
realepath = fd.getDirectory()+fd.getFile();
if(fd.getFile() != null) {
//打開時將記事本標題替換
frame.setTitle(fd.getFile());
readFile(realepath,textArea);
}
}
private static void readFile(String path,TextArea textArea){
if("nullnull".equals(path) || !new File(path).exists()) {
return;
}
textArea.setText("");
// TODO Auto-generated method stub
//獲取要讀取文件的目錄
File file = new File(path);
try {
//指定讀取文件
FileInputStream fin = new FileInputStream(file);
/*byte[] b = new byte[fin.available()];
fin.read(b);
//將字符數組轉成字符串
String s = new String(b);*/
byte[] b = new byte[5];
int len;
while((len = fin.read(b)) != -1) {
textArea.append(new String(b,0,len));
}
// textArea.setText(s);
fin.close();
} catch (FileNotFoundException e) {
// TODO: handle exception
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
保存功能
/**
* 保存功能
* 點擊保存之後,
* 調用保存方法,將從打開問價時獲取到的文件路徑傳入,
* 創建字符輸出流對象將記事本文本框中的內容寫入到源文件中
* 實現了保存
* 如果是打開的本地文件,直接保存
* 如果要保存的文件是新建的文件(在本地沒有存檔)
* 可以將記事本的標題欄默認設置爲無標題,如果打開了文件則將標題替換
* 保存時查詢標題即可知道是否是本地文件
* 是本地文件直接獲取文本框內容保存
* 不是本地文件,直接調用另存
*
*/
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JFrame;
public class SaveActionListener implements ActionListener {
TextArea ta;
JFrame frame = new JFrame();
public SaveActionListener(TextArea ta, JFrame frame) {
super();
this.ta = ta;
this.frame = frame;
}
@Override
public void actionPerformed(ActionEvent e) {
if(frame.getTitle().equals("無標題")) {
new SaveAsActionListener(frame, ta).actionPerformed(e);
}else {
saveFile(OpenActionListener.realepath);
}
}
private void saveFile(String path) {
FileWriter fw;
try {
fw = new FileWriter(path);
fw.write(ta.getText());
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
另存功能
import java.awt.FileDialog;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JTextArea;
/**
* 另存爲功能
* 獲取到要保存的路徑
* 創建FileOutputStream
*
* @author xer
*
*/
public class SaveAsActionListener implements ActionListener{
JFrame frame = new JFrame();
private TextArea txArea;
String realPath;
public SaveAsActionListener(JFrame frame, TextArea txArea) {
super();
this.frame = frame;
this.txArea = txArea;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
try {
FileDialog fd = new FileDialog(frame,"save",FileDialog.SAVE);
fd.setVisible(true);
realPath = fd.getDirectory()+fd.getFile();
writeFile(realPath, txArea);
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
private void writeFile(String path,TextArea textArea) {
if("nullnull".equals(path)) {
return;
}
//輸出流
File file = new File(path);
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
//獲取記事本文本框內的內容寫入到要保存的文件中
fileOutputStream.write(txArea.getText().getBytes());
fileOutputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
退出功能
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ExitActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
}
記錄一些遺漏:最開始沒有考慮到在打開或者保存對話框時沒有判斷文件名是否合法,導致出現一些異常