学习IO流

IO流

使用FileWriter复制文件

public static void main(String[] args) throws IOException {

    //1,读取一个已有的文本文件,使用字符读取流和文件相关联。
    FileReader fr = new FileReader("IO流_2.txt");
    //2,创建一个目的,用于存储读到数据。
    FileWriter fw = new FileWriter("copytext_1.txt");
    //3,频繁的读写操作,这是从缓冲区中读取,是高效的读取,每次只读取一个,结束标记是返回-1的时候表示读取结束。
    int ch = 0;
    while((ch=fr.read())!=-1){
        fw.write(ch);
    }
    //4,关闭流资源。 

    fw.close();
    fr.close();
}

使用缓冲区,提高效率

//定义缓冲区的大小
private static final int BUFFER_SIZE = 1024;

/**
 * @param args
 */
public static void main(String[] args) {

    FileReader fr = null;
    FileWriter fw = null;
    try {
        fr = new FileReader("IO流_2.txt");
        fw = new FileWriter("copytest_2.txt");

        //创建一个临时容器,用于缓存读取到的字符。
        char[] buf = new char[BUFFER_SIZE];//这就是缓冲区。 

        //定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数 )
        int len = 0;

        //提高效率的原理:读取的时候读取了多个数据,并放到了数组中,
        //写的时候写入数组中的数据,这样就减少了内存和硬盘交互的次数,因此提高了效率,当buf里面没有数据时,read方法就会返回-1
        while((len=fr.read(buf))!=-1){
            fw.write(buf, 0, len);
        }

    } catch (Exception e) {
//          System.out.println("读写失败");
        throw new RuntimeException("读写失败");
    }finally{
        if(fw!=null)
            try {
                fw.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        if(fr!=null)
            try {
                fr.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
    }
}

使用java内置的高效字节流完成文件复制

public static void main(String[] args) throws IOException {

    FileReader fr = new FileReader("buf.txt");      
    BufferedReader bufr = new BufferedReader(fr);

    FileWriter fw = new FileWriter("buf_copy.txt");
    BufferedWriter bufw = new BufferedWriter(fw);


    String line = null;
    //readLine是读取一行数据,如果没有,则返回null
    while((line=bufr.readLine())!=null){
        bufw.write(line);
        bufw.newLine();
        bufw.flush();
    }
    /*
    int ch = 0;

    while((ch=bufr.read())!=-1){

        bufw.write(ch);
    }
    */
    bufw.close();
    bufr.close();
}

使用LineNumberReader打印行数

public static void main(String[] args) throws IOException {

    FileReader fr = new FileReader("IO流_2.txt");
    LineNumberReader lnr = new LineNumberReader(fr);

    String line = null;
    //设置起始的行数
    lnr.setLineNumber(100);
    while((line=lnr.readLine())!=null){
        System.out.println(lnr.getLineNumber()+":"+line);
    }

    lnr.close();
}

练习:文件深度遍历

public static void main(String[] args){
    File dir = new File("e:\\demodir");
    listAll(dir , 0);
}

public static void listAll(File dir , int level){

//打印文件夹名称
System.out.println(getSpace(level) + dir.getName() );

//每执行一次这个方法就表示增加了一次层级
level++;

//获取当前目录下的文件和文件夹,返回一个数组
File[] files = dir.listFiles();

for(int x = 0 ; x < files.length ; x++){
    //判断是否是文件夹
    if(files[x].isDirectory()){
        //是文件夹,递归执行listAll
        listAll(files[x] , level);
    }else{
        //是文件,打印文件名
        System.out.println(getSpace(level) + files[x].getName() );
    }
}
}

//根据目录的层级计算缩进
private static String getSpace(int level){
    StringBuilder sb = new StringBuilder();
    sb.append("|--");

    for(int x = 0 ; x < level ; x++){
        sb.insert(0 , "|  ");
    }

    return sb.toString();
}

练习:删除一个带内容的目录

public static void main(String[] args){
    File dir = new File("e:\\demodir");
    removeDir(dir);
}

public static void removeDir(File dir){
    File[] files = dir.listFiles();

    for(File file : files){
        if(file.isDirectory()){
            removeDir(file);
        }else{
            System.out.println(file + ":" + file.delete() );
            delete();
        }
    }

    //for循环结束之后,目标文件夹中的数据都被删除了,最后删除目标文件夹即可
    System.out.println(dir + ":" + dir.delete() );
}

练习:程序计数器

/*定义功能:获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示.并退出程序
思路:
    1.需要一个配置文件供程序读取,里面保存着程序运行的次数
    2.每次程序运行过后都修改里面的参数,加一

public static void main(String[] args) throws IOException  {    
    getAppCount();  
}

public static void getAppCount() throws IOException{
    //读取配置文件,封装成file对象
    File confile = new File("count.properties");

    //判断配置文件是否存在
    if(!confile.exists){
        //不存在,创建配置文件
        confile.createNewFile();
    }
    //使用流读取配置文件
    FileInputStream fis = new FileInputStream(confile);
    //使用Properties读取properties配置文件
    Properties prop = new Properties();
    //从流中装载配置文件信息
    prop.load(fis);
    //从集合中通过键获取次数
    String value = prop.getProperty("time");

    //定义计数器,记录获取到的次数
    int count = 0;
    if(value != null){
        //把字符串转为int类型
        count = Integer.parseInt(value);
        if(count >= 5){
            throw new RuntimeException("使用次数已到 , 请注册 , 给钱! ");
        }
    }

    count++;
    //将改变后的次数重新存储到集合中
    prop.setProperty("time" , count + "");

    //把集合中修改后的数据写回文件中
    FileOutputStream fos = new FileOutputStream(confile);
    prop.store(fos , "");
    fos.close();
    fis.close();
}
*/

练习:获取指定目录下,指定扩展名的文件

public static void main(String[] args) throws IOException {
    //把指定的文件夹封装为File对象
    File dir = new File("e:\\java0331");

    //创建一个文件过滤器,使用内部类的写法
    FilenameFilter filter = new FilenameFilter(){
        @Override
        public boolean accept(File dir , String name){
            return name.endsWith(".java");
        }
    };

    //使用集合装符合条件的文件
    List<File> list = new ArrayList<File>();

    getFiles(dir , filter , list);

    #数据写入的目标文件
    File destFile = new File(dir , "javalist.txt");

    #写入文件
    write2File(list , destFile);
}


#根据输入的目录,文件过滤器,寻找符合条件的文件,放入集合中,并返回这个集合
public static void getFiles(File dir , FilenameFilter filter , List<File> list ){
    //获取当前文件夹下的所有文件和文件夹
    File[] files = dir.listFiles();

    //使用for循环判断哪些是文件,哪些是文件夹
    for(File file : files){
        if( file.isDirectory() ){
            //是文件夹,递归执行此方法
            getFiles(file , filter , list);
        }else{
            //不是文件,把符合条件的文件放入集合
            if(filter.accept(dir , file.getName() ) ){
                //符合过滤器条件
                list.add(file);
            }
        }
    }
}


public static void write2File(List<File> list , File destFile) throws IOException{
    BufferedWriter bufw = null;
    try{
        bufw = new BufferedWriter(new FileWriter(destFile) );
        for(File file : list){
            bufw.write(file.getAbsolutePath() );
            bufw.newLine();
            bufw.flush();
        }finally{
            try {
                bufw.close();
            } catch (IOException e) {

                throw new RuntimeException("关闭失败");
            }           
        }
    }
}

练习:文件切割器

public static void main(String[] args) throws Exception {
    File file = new File("c:\\aa.mp3");

    splitFile(file);
}

//将一个完整的文件切分为多个碎片文件
private static void splitFile(File file) throws IOException {
    //使用读取流关联源文件
    FileInputStream fis = new FileInputStream(file);

    //定义一个1M的缓冲区
    byte[] buf = new byte[1024 * 1024];

    //创建目的
    FileOutputStream fos = null

    int len = 0;
    int count = 1;

    /*切割文件时,必须记录被切割文件的名称,以及碎片文件的个数,方便合并,为了描述这些信息,使用键值对的方式,用到了properties对象*/
    Properties prop = new Properties();

    File dir = new File("c:\\partfiles");
    if(!dir.exists()){
        dir.mkdirs();
    }

    while( (len = fis.read(buf)) != -1){
        //每次循环都创建新的输出流对象
        fos = new FileOutputStream(new File(dir , (count++) + ".part"));

        //把读取流读取到的数据(也就是放入buf中的数据)写入到文件中去
        fos.write(buf , 0 , len);
        fos.close();
    }

    //将被切割文件的信息保存到prop集合中
    prop.setProperty("partcount" , count + "");
    prop.setProperty("filename" , file.getName());

    //将prop集合中的数据持久化
    fos = new FileOutputStream(new File(dir + count + ".properties"));

    prop.store(for , "save file info");
    fos.close();
    fis.close();
}

练习:碎片文件合并

public static void main(String[] args) throws IOException {
    File dir = new File("c:\\partfiles");
    mergeFile(dir);
}

public static void mergeFile(File dir) throws IOException {
    //获取指定目录下的配置文件
    File[] files = dir.listFiles(new SuffixFilter(".properties"));

    if(files.length != 1)
        throw new RuntimeException(dir + ",该目录下没有properties扩展名的文件或者不唯一");

    //获取配置文件对象
    File confile = files[0];

    //获取配置文件中的信息
    Properties prop = new Properties();
    FileInputStream fis = new FileInputStream(confile);
    prop.load(fis);
    String filename = prop.getProperty("filename");
    int count = Integer.parseInt(prop.getProperty("partcount"));

    //获取该目录下所有的碎片文件
    File[] partFiles = dir.listFiles(new SuffixFileter(".part"));
    if(partFiles.length != (count - 1)){
        throw new RuntimeException(" 碎片文件不符合要求,个数不对!应该"+count+"个");
    }

    //将碎片文件和流对象关联,并存储到集合中去
    ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    //使用for循环创建多个读取流和每一个配置文件关联起来
    for(int x = 0 ; x < partFiles.length ; x++){
        //创建的读取流放入集合中
        al.add(new FileInputStream(partFiles[x]));
    }

    //将多个流合并为一个序列流
    //使用集合类中方法把输入流的集合转化为枚举集合
    Enumeration<FileInputStream> en = Collections.enumeration(al);
    //构建序列流
    SequenceInputStream sis = new SequenceInputStream(en);
    //输出流和合并之后的文件相关联
    FileOutputStream fos = new FileOutputStream(new File(dir , filename));
    byte[] buf = new byte[1024];
    int len = 0;
    while( (len = sis.read(buf)) != -1){
        fos.write(buf , 0 , len);
    }
    fos.close();
    sis.close();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值