java IO增强

File类

public class FileDemo {
    public static void main(String[] args) throws Exception {
        //创建以test开头temp结尾的临时文件
        File temp = File.createTempFile("test", "temp", new File("F:/DB/test/"));
        Thread.sleep(1000);
        //退出时即删除临时文件
        temp.deleteOnExit();
    }
}
/**
 * list()方法和listFiles()方法的区别
 * @author L J
 */
public class FileDemo2 {
    public static void main(String[] args) {
        File src = new File("F:/DB/test");
        //取出所有子目录和子文件的名称
        String[] subNames = src.list();
        for(String temp : subNames) {
            System.out.println(temp);
        }

        //取出所有子目录和子文件的File对象
        File[] subFiles = src.listFiles();
        for(File temp : subFiles) {
            System.out.println(temp.getAbsolutePath());
        }

        //命令设计模式
        subFiles = src.listFiles(new FilenameFilter() {
            //dir表示src,name表示文件名
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isFile() && name.endsWith(".txt");
            }
        });

        for(File temp : subFiles) {
            System.out.println(temp.getAbsolutePath());
        }

        //列出所有的根路径
        File[] roots = File.listRoots();
        System.out.println(Arrays.toString(roots));//[C:\, E:\, F:\, G:\, H:\]
    }
}

FileInputStream & FileOutputStream

//读取文件
public class FileInputStreamTest {
    public static void main(String[] args) {
        File src = new File("F:/DB/abc.txt");
        InputStream is = null;
        try {
            is = new FileInputStream(src);
            //字节数组
            byte[] buf = new byte[1024];
            int len = 0;
            //读取
            while(-1 != (len = is.read(buf))) {
                String info = new String(buf, 0, len);
                System.out.println(info);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭流
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//写文件
public class FileOutputStreamTest {
    public static void main(String[] args) {
        File dest = new File("F:/DB/abc.txt");
        OutputStream os = null;
        try {
            //true表示追加,false表示覆盖
            os = new FileOutputStream(dest, true);
            String str = "bjsxt is very good\r\n";
            //获取字节数组
            byte[] data = str.getBytes();
            os.write(data, 0, data.length);
            os.flush(); //强制刷新出去
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //关闭流
            if(os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件拷贝和目录拷贝

/**
 * 文件工具类
 * 1、拷贝文件
 * 2、拷贝文件夹
 * @author L J
 */
public class FileUtils {

    /**
     * 拷贝文件
     * 
     * @param src
     *            文件源路径
     * @param dest
     *            文件目标路径
     * @throws IOException
     */
    public static void copyFile(String src, String dest) throws IOException {
        copyFile(new File(src), new File(dest));
    }

    /**
     * 拷贝文件
     * 
     * @param src
     *            文件源路径的File对象
     * @param dest
     *            文件目标路径的File对象
     * @throws IOException
     */
    public static void copyFile(File src, File dest) throws IOException {
        if(! src.isFile()) {//是目录或为null
            throw new IOException("只能拷贝文件");
        }

        //dest为已经存在的目录,不能建立与目录名字相同的文件
        if(dest.isDirectory()) {
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹名字相同的文件");
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        // 输入输出流
        fis = new FileInputStream(src);
        fos = new FileOutputStream(dest);

        byte[] buf = new byte[1024];
        int len = 0;

        // 拷贝文件
        while (-1 != (len = fis.read(buf))) {
            fos.write(buf, 0, len);
        }
        fos.flush(); //强制刷出
        //关闭流
        fos.close();
        fis.close();
    }

    /**
     * 拷贝文件夹
     * @param srcPath 源路径
     * @param destPath 目标路径
     */
    public static void copyDir(String srcPath, String destPath) {
        File src = new File(srcPath);
        File dest = new File(destPath);
        copyDir(src, dest);
    }

    /**
     * 拷贝文件夹
     * @param src 源目录File对象
     * @param dest 目标目录File对象
     */
    public static void copyDir(File src, File dest) {
        if(src.isDirectory()) {//文件夹
            dest = new File(dest, src.getName());
        }
        copyDirDetai(src, dest);
    }

    /**
     * 拷贝文件夹细节
     * @param src 源目录File对象
     * @param dest 目标目录File对象
     */
    public static void copyDirDetai(File src, File dest) {
        if(src.isFile()) {  //文件
            try {
                FileUtils.copyFile(src, dest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(src.isDirectory()) {//文件夹
            //确保目标文件夹存在,有就不创建,没有就创建
            dest.mkdirs();
            //获取下一级目录|文件
            for(File sub : src.listFiles()) {
                //递归
                copyDirDetai(sub, new File(dest, sub.getName()));
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 源文件
        String src = "F:/DB/abc.txt";
        // 拷贝后的文件
        String dest = "F:/DB/test/abc.txt";
        copyFile(src, dest);
    }
}
/**
 * 文件夹的拷贝
 * 1、如果是文件,拷贝
 * 2、如果是文件夹,创建
 * @author L J
 */
public class CopyDir {
    public static void main(String[] args) {
        //源目录
        String srcPath = "F:/DB/test";
        //目标目录
        String destPath = "F:/DB/dest";

        //File src = new File(srcPath);
        //File dest = new File(destPath);

        FileUtils.copyDir(srcPath, destPath);
    }
}

InputStreamReader & OutputStreamWriter

将字节流转换为字符流,主要用来解决乱码问题

  • 编码: 字符–编码字符集–>二进制
  • 解码:二进制–解码字符集–>字符

造成乱码的一般原因:

  • 编码与解码的字符集不统一
  • 字节缺少,长度丢失
/**
 * 乱码成因分析
 * @author L J
 */
public class ConverDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //test1();
        test2();
    }

    /**
     * 字节数不完整,乱码
     */
    public static void test2() {
        String str = "程序员";
        byte[] data = str.getBytes();
        //字节数不完整
        System.out.println(new String(data, 0, 3));
    }

    /**
     * 编码与解码字符集必须统一,否则乱码
     * @throws UnsupportedEncodingException
     */
    public static void test1() throws UnsupportedEncodingException {
        //解码byte-->char
        String str = "程序员"; //GBK
        //编码char-->byte
        byte[] data = str.getBytes();
        //编码与解码字符集统一
        System.out.println(new String(data));  //程序员

        //设定编码字符集
        data = str.getBytes("UTF-8");
        //编码与解码字符集不统一,乱码
        System.out.println(new String(data));  //绋嬪簭鍛?

        //编码
        byte[] data2 = "程序员".getBytes("UTF-8");
        //解码
        str = new String(data2, "UTF-8");
        System.out.println(str);
    }
}

字节数组流和文件流的对接

/**
 * 文件复制
 * 1、文件--程序-->字节数组 
 * 2、字节数组--程序-->文件
 * @author L J
 */
public class ByteArrayDemo {
    public static void main(String[] args) throws IOException {
        byte[] data = getBytesFromFile("F:/DB/abc.txt");
        toFileFromByteArray(data, "F:/DB/def.txt");
    }

    /**
     * 字节数组--程序-->文件
     * @param src 源字节数组
     * @throws IOException 
     */
    public static void toFileFromByteArray(byte[] src, String destPath) throws IOException {
        //目的地
        File dest = new File(destPath);
        //字节数组输入流
        InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
        //文件输出流
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));

        //不断的从字节数组向文件中写数据
        byte[] buf = new byte[1024];
        int len = 0;
        while(-1 != (len = is.read(buf))) {
            os.write(buf, 0, len);
        }
        os.flush();

        //关闭流
        os.close();
        is.close();
    }

    /**
     * 文件--程序-->字节数组
     * 
     * @param srcPath
     *            源文件路径
     * @return 从文件获取的字节数组
     * @throws IOException
     */
    public static byte[] getBytesFromFile(String srcPath) throws IOException {
        // 创建文件源
        File src = new File(srcPath);
        // 创建字节数组目的地
        byte[] dest = null;
        // 文件输入流
        InputStream is = new BufferedInputStream(new FileInputStream(src));
        // 字节输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        // 不断从文件读取数据,向字节数组写数据
        byte[] buf = new byte[1024];
        int len = 0;
        while (-1 != (len = is.read(buf))) {
            bos.write(buf, 0, len);
        }
        bos.flush();
        dest = bos.toByteArray();

        // 关闭流
        bos.close();
        is.close();

        return dest;
    }
}

DataInputStream & DataOutputStream

处理流,对基本数据类型和字符串进行操作

打印流

/**
 * 打印流(重定向)
 * System.in
 * System.out
 * System.err
 * @author L J
 */
public class PrintStreamDemo {
    public static void main(String[] args) throws IOException {
        //输出重定向,PrintStream(OutputStream out, boolean autoFlush)
        //true表示自动刷出,不用手动刷出
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("F:/DB/def.txt")),true));
        System.out.println("哈哈");

        //输出重定向到控制台
        //FileDescriptor.out外必须包装一个文件输出流
        //FileDescriptor.in
        //FileDescriptor.err
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));
        System.out.println("哈哈");
    }
}

装饰模式

//声音
public class Voice {
    private int voice = 10;
    public Voice() {
    }
    public int getVoice() {
        return voice;
    }
    public void setVoice(int voice) {
        this.voice = voice;
    }
    public void say() {
        System.out.println(voice);
    }
}
//扩音器
public class Amplifier {
    private Voice voice;
    public Amplifier() {
    }
    public Amplifier(Voice voice) {
        super();
        this.voice = voice;
    }
    public void say() {
        //放大音量
        System.out.println(voice.getVoice() * 1000);
    }
}
/**
 * 装饰模式
 * 类与类之间的关系
 * 1、依赖:形参|局部变量
 * 2、关联:属性
 *      1)聚合:整体与部分的关系 不一致的生命周期(人与手)
 *      2)组合:整体与部分的关系 一致的生命周期(人与大脑)
 * 3、继承:父子类关系
 * 4、实现:接口与实现类关系
 * @author L J
 */
public class DecoraterDemo {
    public static void main(String[] args) {
        Voice v = new Voice();
        v.say(); //10

        Amplifier am = new Amplifier(v);
        am.say(); //10000
    }
}

文件的分割与合并

RandomAccessFile类的使用:

/**
 * 文件的分割与合并
 * 1、分割的块数 n块
 * 2、每一块的大小 blocksize
 * 3、最后一块文件的大小:总的文件的大小-(n-1)*blocksize
 * @author L J
 */
public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile rnd = new RandomAccessFile(new File("F:/DB/def.txt"), "r");
        rnd.seek(20);
        //定义缓冲大小
        byte[] buf = new byte[1024];
        //接收长度
        int len = 0;
        while(-1 != (len = rnd.read(buf))) {
            if(len > 20) {
                System.out.println(new String(buf, 0, 20));
                break;
            }else{
                System.out.println(new String(buf, 0, len));
            }
        }

        //关闭流
        FileUtils.colse(rnd);
    }
}

文件的分割与合并:

//文件分割
public class SplitFile {
    //文件的路径
    private String filePath;
    //文件名
    private String fileName;
    //文件大小
    private long length;
    //块数
    private int size;
    //每块的大小
    private long blocksize;
    //分割后的存放目录
    private String destBlockPath;
    //每块的名称
    private List<String> blockName;

    public SplitFile() {
        blockName = new ArrayList<String>();
    }

    public SplitFile(String filePath, String destBlockPath) {
        this(filePath, destBlockPath, 1024);
    }

    public SplitFile(String filePath, String destBlockPath, long blockSize) {
        this();
        this.filePath = filePath;
        this.destBlockPath = destBlockPath;
        this.blocksize = blockSize;
        init();
    }

    //确定每块的名字
    private void initBlockName() {
        for(int i = 0; i < size; i++) {
            this.blockName.add(destBlockPath + "/" + this.fileName + i);
        }
    }

    //初始化操作 计算块数,确定文件名和块名
    public void init() {
        File src = null;

        //文件路径为空或不存在
        if(null == filePath || !(src = new File(filePath)).exists()) {
            return;
        }
        //文件夹
        if(src.isDirectory()) {
            return;
        }

        //文件名
        this.fileName = src.getName();
        //文件总大小
        this.length = src.length();
        //修正每块的大小
        if(this.blocksize > length) {
            this.blocksize = length;
        }

        //确定块数
        size = (int)(Math.ceil(length * 1.0 / this.blocksize));
        initBlockName();
    }

    /**
     * 文件分割
     * 1、第几块
     * 2、起始位置
     * 3、块实际大小
     * @param destPath 分割后的文件存放目录
     */
    public void split(String destPath) {
        long beginPos = 0; //起始点,默认从0开始
        long actualBlocksize = blocksize; //块实际大小,默认为1024字节
        for(int i = 0; i < size; i++) {
            if(i == size - 1) { //最后一块
                actualBlocksize = length - beginPos;
            }
            splitDetail(i, beginPos, actualBlocksize);
            beginPos += actualBlocksize; //本次的终点,下一次的起点
        }
    }

    /**
     * 文件分割的细节
     * @param index 第几块
     * @param beginPos 起始位置
     * @param actualBlocksize 实际大小
     */
    public void splitDetail(int index, long beginPos, long actualBlocksize) {
        //创建源
        File src = new File(this.filePath); //源文件
        File dest = new File(this.blockName.get(index)); //目标文件
        //选择流
        RandomAccessFile raf = null;
        BufferedOutputStream bos= null;
        try {
            raf = new RandomAccessFile(src, "r");
            bos = new BufferedOutputStream(new FileOutputStream(dest));
            //读取文件
            raf.seek(beginPos);
            //缓冲区
            byte[] buf = new byte[1024];
            //接收长度
            int len = 0;
            while(-1 != (len = raf.read(buf))) {
                if(actualBlocksize - len >= 0) { //查看是否足够
                    bos.write(buf, 0, len);
                    actualBlocksize -= len; //剩余量
                }else{
                    bos.write(buf, 0, (int)actualBlocksize);
                    break;
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            FileUtils.close(bos, raf);
        }
    }

    //文件的合并
    public void mergeFile(String destPath) {
        //创建源
        File dest = new File(destPath);
        //选择流
        BufferedOutputStream bos = null; //输出流
        BufferedInputStream bis = null;  //输入流

        try {
            bos = new BufferedOutputStream(new FileOutputStream(dest, true));
            for(int i = 0; i < this.blockName.size(); i++) {
                bis = new BufferedInputStream(new FileInputStream(new File(this.blockName.get(i))));
                //缓冲区
                byte[] buf = new byte[1024];
                //接收长度
                int len = 0;
                while(-1 != (len = bis.read(buf))) {
                    bos.write(buf, 0, len);
                }
                bos.flush();
                FileUtils.close(bis);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            FileUtils.close(bos);
        }
    }

    //文件的合并,
    public void merge(String destPath) throws IOException {
        //创建源
        File dest = new File(destPath);
        //选择流
        BufferedOutputStream bos = null; //输出流
        SequenceInputStream sis = null;  //输入流

        //创建一个容器
        Vector<InputStream> vi = new Vector<InputStream>();
        for(int i = 0; i < this.blockName.size(); i++) {
            vi.add(new BufferedInputStream(new FileInputStream(new File(this.blockName.get(i)))));
        }

        //序列输入流,需要一个枚举输入
        sis = new SequenceInputStream(vi.elements());

        try {
            bos = new BufferedOutputStream(new FileOutputStream(dest, true));
            sis = new SequenceInputStream(vi.elements());
            //缓冲区
            byte[] buf = new byte[1024];
            //接收长度
            int len = 0;
            while(-1 != (len = sis.read(buf))) {
                bos.write(buf, 0, len);
            }
            bos.flush();
            FileUtils.close(sis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            FileUtils.close(bos);
        }
    }

    public static void main(String[] args) throws IOException {
        SplitFile splitFile = new SplitFile("F:/DB/students.xls", "F:/DB/dest",30);
        splitFile.split("F:/DB/dest");
        splitFile.merge("F:/DB/gh.xls");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值