6、IO(2)

2.7 打印流

package cn.itcast.day159.stream;
import java.io.*;
import java.util.Scanner;
/*
 * 三个常量
 * 1、System.in
 * 2、System.out
 * 3、System.err
 * 其中后面两个实质上没有区别,只是会给错误加上颜色以示区别
 * FileDescriptor.out:表示控制台输出
 * FileDescriptor.in:表示控制台输入
 * */
public class Demo03 {
    public static void main(String[] args) throws FileNotFoundException {
        test1();
    }
    
    public static void test3() throws FileNotFoundException{
        System.out.println("test");//输出到控制台
        //重定向
        File src = new File("D:/FQ/parent/data.txt");
        //true表示自动刷新
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(src)), true));
        System.out.println("test");//打印输出到文件
        //再次重定向到控制台
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true));
        System.out.println("test");
    }
    
    public static void test2() {
        InputStream is = System.in;//标准键盘输入
        //is = new BufferedInputStream(new FileInputStream("D:/FQ/parent/data.txt"));
        Scanner sc = new Scanner(is);//这里is是一个输入流,于是我们可以替换为其他的输入流,比如文件输入流,如上
        System.out.println("请输入: ");
        System.out.println(sc.nextLine());
    }
    
    public static void test1(){
        System.out.println("test");
        System.err.println("err");//会自动加上颜色
    }
}

说明:打印流也是一个处理流,这个流方便我们控制输入输出的位置。使用较为简单,这里不多数。

三、文件夹拷贝

在对文件夹进行拷贝的时候我们不仅要拷贝子孙目录,同时对于目录中的文件也需要进行拷贝。

package cn.itcast.day146.stream;
import java.io.File;
import java.io.IOException;
//文件夹的拷贝
//如果目标是一个文件夹则我们需要创建,如果是一个文件则直接拷贝即可
public class DirCopy {
    public static void main(String[] args) {
        String srcPath = "D:/FQ/parent";
        File src = new File(srcPath);
        String destPath = "D:/FQ/parent_back";
        File dest = new File(destPath);
        copy(src, dest);
    }
    //拷贝文件夹
    private static void copyDir(File src, File dest) {
        if(src.isFile()){
            try {
                FileCopyUtil.fileCopy(src, dest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(src.isDirectory()){
            //确保目标文件夹存在
            dest.mkdirs();
            //获取子孙级
            for(File sub : src.listFiles()){
                copyDir(sub, new File(dest, sub.getName()));
            }
        }
    }
    
    //封装成一个工具类
    public static void copy(File src, File dest){
        //之所以有下面这个判断,是因为我们不仅需要将源文件夹中内容拷贝,
        //同时还要将源文件夹拷贝,也就是要将最上一级的目录拷贝下来
        if(src.isDirectory()){//如果是目录
            dest = new File(dest, src.getName());
            System.out.println(dest);//D:\FQ\parent_back\parent
        }
        copyDir(src, dest);
    }
    public static void copy(String srcPath, String destPath){
        File src = new File(srcPath);
        File dest = new File(destPath);
        copy(src, dest);
    }
}

说明:程序中对文件的拷贝可以使用之前的程序,这里就不再给出了。

四、文件的分割与合并

package cn.itcast.day159.stream;
import java.io.*;
import java.util.*;
import cn.itcast.day189.socket_.CloseUtil;

public class Demo07 {
    private String filePath;// 文件的路径
    private long blockSize;// 每块的大小
    private int size;// 块数
    private List<String> blockPath;// 各块的名字
    private String fileName;// 文件名
    private long length;// 文件大小
    private String destPath;//分割后的存放目录

    public Demo07() {
        blockPath = new ArrayList<String>();
    }

    public Demo07(String filePath, String destPath) {
        this(filePath, 1024, destPath);
    }

    public Demo07(String filePath, long blockSize, String destPath) {
        this.filePath = filePath;
        this.destPath = destPath;
        this.blockSize = blockSize;
        init();
    }

    // 初始化操作,计算块数和文件名
    public void init() {
        File src = null;
        if (filePath == null || !((src = new File(filePath)).exists())) {
            return;
        }
        // 如果不是文件,而是目录,不能分割
        if (src.isDirectory()) {
            return;
        }
        // 文件名
        this.fileName = src.getName();
        // 计算块数
        this.length = src.length();
        // 如果blockSize比文件实际大小还大
        if (this.blockSize > length) {
            this.blockSize = length;
        }
        // 确定块数,ceil表示取大于等于参数值的最小整数,两个整数相除的时候有可能为0,这里乘上一个1.0
        this.size = (int) (Math.ceil(length * 1.0 / this.blockSize));
        initPathName();// 确定文件路径
    }

    private void initPathName() {
        for (int i = 0; i < size; i++) {
            String str = this.destPath + "/" + this.fileName + ".part" + i;
            this.blockPath.add(str);// 添加一个文件路径
        }
    }

    // 文件分割
    // 第几块、起始位置、实际大小
    // destPath:分割文件的存放目录
    public void split(String destPath) {
        long beginPos = 0;// 起始点
        long actualBlockSize = blockSize;// 实际大小
        // 计算所有块的大小、索引、位置
        for (int i = 0; i < size; i++) {
            if (i == size - 1) {
                actualBlockSize = this.length - beginPos;
            }
            splitDetail(i, beginPos, actualBlockSize);
            beginPos += actualBlockSize;
        }
    }
    /*
     * 文件的拷贝
     */
    private void splitDetail(int index, long beginPos, long actualBolockSize) {
        // 创建源
        File src = new File(this.filePath);
        File dest = new File(this.blockPath.get(index));
        RandomAccessFile raf = null;// 输入流
        BufferedOutputStream bos = null;// 输出流
        // 选择流
        try {
            raf = new RandomAccessFile(src, "r");
            bos = new BufferedOutputStream(new FileOutputStream(dest));
            // 读取文件
            raf.seek(beginPos);//设置读取的起始位置
            byte[] buffer = new byte[1024];
            int len = 0;
            while (-1 != (len = raf.read(buffer))) {
                // 写出
                if (actualBolockSize - len >= 0) {
                    bos.write(buffer, 0, len);
                    actualBolockSize -= len;
                } else {
                    // 写出剩余量
                    bos.write(buffer, 0, (int) actualBolockSize);
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            CloseUtil.closeAll(bos, raf);
        }
    }

    // 文件的合并
    public void mergeFile1(String destPath) {
        // 创建源
        File dest = new File(destPath);
        // 选择流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;// 输出流
        try {
            bos = new BufferedOutputStream(new FileOutputStream(dest, true));// true表示追加
            for (int i = 0; i < this.blockPath.size(); i++) {
                bis = new BufferedInputStream(new FileInputStream(
                        this.blockPath.get(i)));

                byte[] buffer = new byte[1024];
                int len = 0;
                while (-1 != (len = bis.read(buffer))) {
                    bos.write(buffer, 0, len);
                }
                bos.flush();
                CloseUtil.closeAll(bis);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            CloseUtil.closeAll(bos);
        }
    }

    // 文件合并,使用SequenceInputStream
    public void mergeFile2(String destPath) {
        // 创建源
        File dest = new File(destPath);
        // 选择流
        // 创建一个容器
        Vector<InputStream> vi = new Vector<InputStream>();
        SequenceInputStream sis = null;
        BufferedOutputStream bos = null;// 输出流

        try {
            for (int i = 0; i < this.blockPath.size(); i++) {
                vi.add(new BufferedInputStream(new FileInputStream(
                        this.blockPath.get(i))));
            }

            bos = new BufferedOutputStream(new FileOutputStream(dest, true));// true表示追加
            sis = new SequenceInputStream(vi.elements());

            byte[] buffer = new byte[1024];
            int len = 0;
            while (-1 != (len = sis.read(buffer))) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
            CloseUtil.closeAll(sis);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            CloseUtil.closeAll(bos);
        }
    }

    public static void main(String[] args) {
        Demo07 file = new Demo07("D:/FQ/parent/copy.txt", 500, "D:/FQ/parent");
        // System.out.println(file.size);
        // file.split("D:/FQ/parent");// 给出存放目录
        file.mergeFile1("D:/FQ/parent/merge.txt");
    }
}

说明:

  • 文件的分割时,我们使用了RandomAccessFile流,这个流可以设置读取文件的位置,便于进行文件的分割。而在文件合并的时候我们可以使用一般的方式,也可以使用SequenceInputStream这个类,这个流是一个合并流。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,892评论 25 707
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,151评论 2 34
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,642评论 18 139
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,217评论 9 467
  • 听完音频首先让我想到的是王子犯法与庶民同罪,不管你的官职有多大,关系有多硬,违反原则理当受到响应的惩罚。在我...
    城市格调刘姣阅读 153评论 0 0