⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystem.java

📁 java编写的简易留言本
💻 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 + -