📄 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"分隔
* 每列用","分隔
* 每列都是包含在两个双引号之间的字符串
* 特殊字符使用转义字符表示"\\","\r","\n,"\"","\'","\t"
*
* @since 2006-01-12 00:45
* @author Lingo
* @version 1.0
*/
public class FileSystem {
/**
* 记录的行数.
*/
private int count;
/**
* 序列号.
*/
private int sequence;
/**
* 保存所有记录的列表.
*/
private List all = null;
/**
* 保存数据的文件.
*/
private File file;
/**
* 文件最后修改时间.
*/
private long lastModifiedTime;
/**
* 构造方法,根据指定的文件名,确定保存数据的文件的位置.
* @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("文件不存在,自动创建一个新文件");
try {
file.createNewFile();
} catch (IOException ex) {
//抛出一个状态错误的unchecked exception
//请注意,这个异常不是必须使用try捕获的
throw new IllegalStateException("无法创建新文件 : "
+ file.getAbsolutePath());
}
}
if (file.exists() && file.isDirectory()) {
System.out.println("输入的是一个目录,请指定一个文件");
//抛出一个状态错误的unchecked exception
//请注意,这个异常不是必须使用try捕获的
throw new IllegalArgumentException(file.getAbsolutePath());
}
lastModifiedTime = file.lastModified();
}
/**
* 听从朱冰老大的话,在操作文件之前首先对文件的权限进行检测.
*
* @since 2006-02-12 00:34
* @author Lingo
* @throws Exception 可能抛出任何异常,没好好想
*/
private void checkValid() throws Exception {
if (file.exists()) {
//如果用户对文件没有读或写的权限,就报错
if (!file.canRead()) {
throw new RuntimeException("权限不足,无法读取文件。");
}
if (!file.canWrite()) {
throw new RuntimeException("权限不足,无法写入文件。");
}
if (file.isDirectory()) {
throw new RuntimeException("需要指定一个文件,而不是目录。");
}
} else {
boolean result = file.createNewFile();
if (!result) {
System.out.println("新建文件发生错误。");
}
}
}
/**
* 从文件中读取所有的数据.
*
* @since 2006-01-12 00:43
* @author Lingo
* @return List 记录的列表
* @throws Exception 可能抛出任何异常
*/
public final List findAll() throws Exception {
//检测文件操作权限
//因为每个方法都要调用这个方法,所以先只在这里加入这个判断
checkValid();
//如果数据还没有读取到内存,就读取一遍
if (all != null) {
//如果文件已经修改,就重新读取
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;
}
/**
* 根据id查找一行数据.
* 如果找不到,就返回null
* @since 2006-01-02 22:02
* @author Lingo
* @param id id
* @return List id对应的数据
* @throws Exception 任何异常
*/
public final List findById(final int id) throws Exception {
//首先保证内存的数据是最新的
//如果文件已经修改过,就先重新读取一遍
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;
}
/**
* 添加一行数据.
* 添加synchronized修饰,只知道应该同步处理,不知道粒度是否正确
*
* @since 2006-01-12 22:14
* @author Lingo
* @param info 插入的数据
* @throws Exception 任何异常
*/
public final synchronized void insert(final List info)
throws Exception {
//首先保证内存的数据是最新的
//如果文件已经修改过,就先重新读取一遍
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();
}
/**
* 修改一行数据.
* 添加synchronized修饰,只知道应该同步处理,不知道粒度是否正确
*
* @since 2006-01-14 22:15
* @author Lingo
* @param info 需要修改的数据
* @throws Exception 任何异常
*/
public final synchronized void update(final List info)
throws Exception {
//首先保证内存的数据是最新的
//如果文件已经修改过,就先重新读取一遍
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;
}
}
}
/**
* 删除一列数据.
* 添加synchronized修饰,只知道应该同步处理,不知道粒度是否正确
*
* @since 2006-01-12 22:15
* @author Lingo
* @param id id
* @throws Exception 任何异常
*/
public final synchronized void delete(final int id)
throws Exception {
//首先保证内存的数据是最新的
//如果文件已经修改过,就先重新读取一遍
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;
}
}
}
/**
* 向文件写一行数据.
* @param row 保存一行数据的列表
* @param writer 输出流
* @throws IOException 写入数据的时候可能抛出异常
*/
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);
}
/**
* 把输入的字符串格式化成可以保存进文件的格式.
* 比如:程序中的换行符号'\n',要转化成"\\n"
* 这样在文件中看到的就是"\n"了,而不是产生换行的效果
*
* @since 2006-01-01 17:44
* @author Lingo
* @param source 需要处理的字符
* @return String 处理结果
*/
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'
* 这里就要把它合成一个字符'\n'
*
* @since 2006-01-01 17:52
* @author Lingo
* @param source 需要处理的字符串
* @return String 结果
*/
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 参数列表
* @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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -