?? filesystem.java
字號:
package anni.tools;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* csv文件保存,讀取工具.
* 每行用"\r\n"分隔
* 每列用","分隔
* 每列都是包含在兩個雙引號之間的字符串
* 特殊字符使用轉(zhuǎn)義字符表示"\\","\r","\n,"\"","\'","\t"
*
* @since 2006-01-12 00:45
* @author Lingo
* @version 1.0
*/
public class FileSystem {
/**
* 記錄的行數(shù).
*/
private int count;
/**
* 序列號.
*/
private int sequence;
/**
* 保存所有記錄的列表.
*/
private List all = null;
/**
* 保存數(shù)據(jù)的文件.
*/
private File file;
/**
* 文件最后修改時間.
*/
private long lastModifiedTime;
/**
* 構(gòu)造方法,根據(jù)指定的文件名,確定保存數(shù)據(jù)的文件的位置.
* @since 2006-01-01 18:16
* @author Lingo
* @param fileName 操作的文件名
*/
public FileSystem(final String fileName) {
file = new File(fileName);
if (!file.exists()) {
System.out.println("文件不存在,自動創(chuàng)建一個新文件");
try {
file.createNewFile();
} catch (IOException ex) {
//拋出一個狀態(tài)錯誤的unchecked exception
//請注意,這個異常不是必須使用try捕獲的
throw new IllegalStateException("無法創(chuàng)建新文件 : "
+ file.getAbsolutePath());
}
}
if (file.exists() && file.isDirectory()) {
System.out.println("輸入的是一個目錄,請指定一個文件");
//拋出一個狀態(tài)錯誤的unchecked exception
//請注意,這個異常不是必須使用try捕獲的
throw new IllegalArgumentException(file.getAbsolutePath());
}
lastModifiedTime = file.lastModified();
}
/**
* 聽從朱冰老大的話,在操作文件之前首先對文件的權(quán)限進(jìn)行檢測.
*
* @since 2006-02-12 00:34
* @author Lingo
* @throws Exception 可能拋出任何異常,沒好好想
*/
private void checkValid() throws Exception {
if (file.exists()) {
//如果用戶對文件沒有讀或?qū)懙臋?quán)限,就報錯
if (!file.canRead()) {
throw new RuntimeException("權(quán)限不足,無法讀取文件。");
}
if (!file.canWrite()) {
throw new RuntimeException("權(quán)限不足,無法寫入文件。");
}
if (file.isDirectory()) {
throw new RuntimeException("需要指定一個文件,而不是目錄。");
}
} else {
boolean result = file.createNewFile();
if (!result) {
System.out.println("新建文件發(fā)生錯誤。");
}
}
}
/**
* 從文件中讀取所有的數(shù)據(jù).
*
* @since 2006-01-12 00:43
* @author Lingo
* @return List 記錄的列表
* @throws Exception 可能拋出任何異常
*/
public final List findAll() throws Exception {
//檢測文件操作權(quán)限
//因為每個方法都要調(diào)用這個方法,所以先只在這里加入這個判斷
checkValid();
//如果數(shù)據(jù)還沒有讀取到內(nèi)存,就讀取一遍
if (all != null) {
//如果文件已經(jīng)修改,就重新讀取
if (lastModifiedTime == file.lastModified()) {
return all;
} else {
lastModifiedTime = file.lastModified();
}
}
all = new ArrayList();
String[] tmp = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String line;
List row;
while ((line = reader.readLine()) != null) {
if (line.equals("")) {
continue;
}
//按"\",\""分隔每一行
tmp = line.split("\",\"");
tmp[0] = tmp[0].substring(1);
String end = tmp[tmp.length - 1];
tmp[tmp.length - 1] = end.substring(0, end.length() - 1);
for (int i = 0; i < tmp.length; i++) {
tmp[i] = getStringFromFile(tmp[i]);
}
row = new ArrayList(Arrays.asList(tmp));
all.add(row);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (reader != null) {
reader.close();
reader = null;
}
}
count = all.size();
sequence = Integer.parseInt(tmp[0]);
return all;
}
/**
* 根據(jù)id查找一行數(shù)據(jù).
* 如果找不到,就返回null
* @since 2006-01-02 22:02
* @author Lingo
* @param id id
* @return List id對應(yīng)的數(shù)據(jù)
* @throws Exception 任何異常
*/
public final List findById(final int id) throws Exception {
//首先保證內(nèi)存的數(shù)據(jù)是最新的
//如果文件已經(jīng)修改過,就先重新讀取一遍
findAll();
List row;
for (int i = 0; i < count; i++) {
row = (List) all.get(i);
if (id == Integer.parseInt((String) row.get(0))) {
return row;
}
}
return null;
}
/**
* 添加一行數(shù)據(jù).
* 添加synchronized修飾,只知道應(yīng)該同步處理,不知道粒度是否正確
*
* @since 2006-01-12 22:14
* @author Lingo
* @param info 插入的數(shù)據(jù)
* @throws Exception 任何異常
*/
public final synchronized void insert(final List info)
throws Exception {
//首先保證內(nèi)存的數(shù)據(jù)是最新的
//如果文件已經(jīng)修改過,就先重新讀取一遍
findAll();
sequence++;
String line;
StringBuffer buff = new StringBuffer();
buff.append('\"').append(sequence);
for (int i = 0; i < info.size(); i++) {
buff.append("\",\"");
line = (String) info.get(i);
line = getStringFromInput(line);
buff.append(line);
}
buff.append('\"');
PrintWriter writer = new PrintWriter(new FileWriter(file, true));
writer.println(buff.toString());
writer.flush();
writer.close();
}
/**
* 修改一行數(shù)據(jù).
* 添加synchronized修飾,只知道應(yīng)該同步處理,不知道粒度是否正確
*
* @since 2006-01-14 22:15
* @author Lingo
* @param info 需要修改的數(shù)據(jù)
* @throws Exception 任何異常
*/
public final synchronized void update(final List info)
throws Exception {
//首先保證內(nèi)存的數(shù)據(jù)是最新的
//如果文件已經(jīng)修改過,就先重新讀取一遍
findAll();
int id = Integer.parseInt((String) info.get(0));
List row;
PrintWriter writer = null;
try {
writer = new PrintWriter(new FileWriter(file));
for (int i = 0; i < count; i++) {
row = (List) all.get(i);
//替代id相同的那一行
if (id == Integer.parseInt(row.get(0).toString())) {
row = info;
}
writeFile(row, writer);
//System.out.println(result);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (writer != null) {
writer.flush();
writer.close();
writer = null;
}
}
}
/**
* 刪除一列數(shù)據(jù).
* 添加synchronized修飾,只知道應(yīng)該同步處理,不知道粒度是否正確
*
* @since 2006-01-12 22:15
* @author Lingo
* @param id id
* @throws Exception 任何異常
*/
public final synchronized void delete(final int id)
throws Exception {
//首先保證內(nèi)存的數(shù)據(jù)是最新的
//如果文件已經(jīng)修改過,就先重新讀取一遍
findAll();
List row;
PrintWriter writer = null;
try {
writer = new PrintWriter(new FileWriter(file));
for (int i = 0; i < count; i++) {
row = (List) all.get(i);
//System.out.println("index : "+i);
//System.out.println(row);
if (id == Integer.parseInt(row.get(0).toString())) {
continue;
}
writeFile(row, writer);
//System.out.println(result);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (writer != null) {
writer.flush();
writer.close();
writer = null;
}
}
}
/**
* 向文件寫一行數(shù)據(jù).
* @param row 保存一行數(shù)據(jù)的列表
* @param writer 輸出流
* @throws IOException 寫入數(shù)據(jù)的時候可能拋出異常
*/
private void writeFile(final List row, final PrintWriter writer)
throws IOException {
StringBuffer buff = new StringBuffer();
buff.append('\"');
String line;
for (int j = 0; j < row.size(); j++) {
line = (String) row.get(j);
//System.out.println(line);
line = getStringFromInput(line);
buff.append(line);
buff.append("\",\"");
}
String result = buff.substring(0, buff.length() - 2);
writer.println(result);
}
/**
* 把輸入的字符串格式化成可以保存進(jìn)文件的格式.
* 比如:程序中的換行符號'\n',要轉(zhuǎn)化成"\\n"
* 這樣在文件中看到的就是"\n"了,而不是產(chǎn)生換行的效果
*
* @since 2006-01-01 17:44
* @author Lingo
* @param source 需要處理的字符
* @return String 處理結(jié)果
*/
private String getStringFromInput(final String source) {
StringBuffer buff = new StringBuffer();
char ch;
int len = source.length();
for (int i = 0; i < len; i++) {
ch = source.charAt(i);
if (ch == '\\') {
buff.append("\\\\");
} else if (ch == '\n') {
buff.append("\\n");
} else if (ch == '\r') {
buff.append("\\r");
} else if (ch == '\t') {
buff.append("\\t");
} else if (ch == '\'') {
buff.append("\\\'");
} else if (ch == '\"') {
buff.append("\\\"");
} else {
buff.append(ch);
}
}
return buff.toString();
}
/**
* 把從文件中讀入的字符串格式化成正常的字符形式.
* 比如:文件中保存的是:"\n",其實內(nèi)存中是兩個字符'\\'和'n'
* 這里就要把它合成一個字符'\n'
*
* @since 2006-01-01 17:52
* @author Lingo
* @param source 需要處理的字符串
* @return String 結(jié)果
*/
private String getStringFromFile(final String source) {
StringBuffer buff = new StringBuffer();
char ch;
int len = source.length();
int index = 0;
while (index < len) {
ch = source.charAt(index);
if (ch == '\\') {
index++;
ch = source.charAt(index);
if (ch == '\\') {
buff.append("\\");
} else if (ch == 'n') {
buff.append('\n');
} else if (ch == 'r') {
buff.append('\r');
} else if (ch == 't') {
buff.append('\t');
} else if (ch == '\'') {
buff.append('\'');
} else if (ch == '\"') {
buff.append('\"');
} else {
throw new IllegalArgumentException("source:" + source
+ "|index:" + index);
}
} else {
buff.append(ch);
}
index++;
}
return buff.toString();
}
/**
* 測試用的main方法.
* @since 2006-01-01 14:52
* @author Lingo
* @param args 參數(shù)列表
* @throws Exception 任何異常
*/
public static final void main(final String[] args)
throws Exception {
FileSystem system = new FileSystem("res/input.txt");
System.out.println(system.findAll() + ", count : " + system.count
+ ", sequence : " + system.sequence);
List list = new ArrayList();
list.add("\\");
list.add("\"");
list.add("\r");
list.add("\n");
list.add("\t");
list.add("\'");
system.insert(list);
System.out.println(system.findAll() + ", count : " + system.count
+ ", sequence : " + system.sequence);
system.delete(4);
System.out.println(system.findAll() + ", count : " + system.count
+ ", sequence : " + system.sequence);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -