黑马程序员-----IO流(3)File类、打印流、序列化、管道流、字符编码等

——- android培训java培训、期待与您交流! ———-

、 File类

1、 创建File对象的3种方式:(封装相对路径或绝对路径都可以)

例:将a.txt封装成file对象
1File f1=new File(“c:\\abc\\a.txt”);
2File f1=new File(“c:\\abc”,”a.txt”);
3File d=new File(“c:\\abc”);
File f1=new File(d,”a.txt”);
     注:separator:与系统有关的默认名称分隔符,因为\\是不跨平台的,所以用separator可以实现跨平台。

2、 File类常见的方法:

1)  创建文件
Boolean createNewFile():在指定位置上创建文件
                        如果文件已经存在,则不创建,返回false
                        如果文件不存在,则创建文件,返回true                          
2)  删除
Boolean delete();删除失败,则返回false
Void deleteOnExit();在程序退出时,删除指定文件
3)  判断
Boolean canExecute();是否能执行
Boolean exists();文件是否存在
isFile();是否是文件
isDirectory();是否是目录
isHidden();是否是隐藏文件
isAbsolute();是否是绝对路径
4)  创建文件夹
Boolean mkdir();创建文件夹(只能是一级文件夹)
Boolean mkdirs();创建多级文件夹
5)  获取信息
getName();获取文件名
getPath();获取文件的相对路径
getParent();得到该文件的父目录路径名
gerAbsolutePath();获取绝对路径
long lastModified();返回最后修改的时间
long length();返回文件的长度(以字节为单位)
renameTo();重命名

3、 文件列表常见方法:

1)  File[] listRoots();列出可用的文件系统根
2)  String[]  list();返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。(调用list方法的file对象必须是封装了一个目录,该目录还必须存在)
3)  String[]  list(FilenameFilter filter);返回一个字符串数组,这些字符串指定此路径名表示的目录中满足指定过滤器的文件和目录。
4)  File[]  listFiles();返回此目录中的文件和目录的File实例数组(对象)。

4、 例子:

例1:列出指定目录下文件或者文件夹包含子目录中的内容,也就是列出指定目录下的内容。

package com.shan;
import java.io.File;
/*
 * 需求:列出指定目录下文件或文件夹,包含子目录中的内容。也就是列出指定目录下的内容
 *  * @param args
 */
public class Demo19 {
    public static void main(String[] args) 
    {
        File  dir=new File("D:\\JAVA 01");
        show(dir);
    }
    public static void show(File dir)
    {
        System.out.println(dir);

        File[] files=dir.listFiles();
        for(int x=0;x<files.length;x++)
        {
            if(files[x].isDirectory())
                show(files[x]);
            else
                System.out.println(files[x]);
        }   
    }
}

例2:删除带内容的目录

package com.shan;
import java.io.File;
/**
 * 需求:删除带内容的目录     除目录是从里面往外删除的,既然是从里往外删,就用到了递归
 * @param args
 */
public class Demo20 {
    public static void main(String[] args) {
        File dir=new File("F:\\那些年的最爱");
        remove(dir);
    }

    public static void remove(File dir) {
        File[] files=dir.listFiles();
        for(int x=0;x<files.length;x++)
        {
            if(!files[x].isHidden()&&files[x].isDirectory())
            {
                remove(files[x]);
            }
            else
                System.out.println(files[x].toString()+files[x].delete());

        }

    }

}

例3:将一个指定目录下的java文件的绝对路径存储到一个文本文件中,建立一个java 文件列表

package com.shan;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**需求:将一个指定目录下的java文件的绝对路径存储到一个文本文件中,建立一个java文件列表
 * 
 * 思路:1、对指定的目录进行递归
 *     2、获取递归过程中所有的java文件的路径
 *     3、将这些路径存入集合中
 *     4、将集合中的数据写入一个文件中
 * * 
 * @param args
 */
public class Demo21 {

    public static void main(String[] args) {
        File dir=new File("d:\\java");
        List<File> list=new ArrayList<File>();
        fileToList(dir,list);
        File file=new File(dir,"javalist.txt");
        writeToFile(list,file.toString());

    }
    public static void fileToList(File dir, List<File> list) 
    {
        File[] files=dir.listFiles();
        for(File file:files)
        {
            if(file.isDirectory())
                fileToList(file,list);
            else
            {
                if(file.getName().endsWith(".java"))
                list.add(file);
            }
        }

    }
    public static void writeToFile(List<File> list, String javaListFile) 
    {
        BufferedWriter bufw=null;
        try
        {
            bufw=new BufferedWriter(new FileWriter(javaListFile));
            for(File f:list)
            {
                String path=f.getAbsolutePath();
                bufw.write(path);
                bufw.newLine();
                bufw.flush();
            }
        }
        catch(IOException e)
        {
            throw new RuntimeException("写入失败!");
        }
        finally
        {
            try
            {
                if(bufw!=null)
                bufw.close();               
            }
            catch(IOException e)
            {
                throw new RuntimeException("关闭失败!");
            }
        }   

    }

}

二、 Properties类(可以和IO流相结合进行操作)

1、Properties是 Hashtable的子类,而Hashtable又是Map的子类,所以它具备了Map集合的特点,并且它里面存放的键值对都是字符串。

2、Map
|–Hashtable
|–Properties

3、特点:
1). 该集合中的键和值都是字符串类型。
2). 集合中的数据可以保存到流中,或者从流中获取。
3). 通常该集合用于操作以键值对形式存在的配置文件。

4、方法:

1)setProperty(String key,String value);//设置属性
2)getProperty(String key);//获取属性  用指定的键在属性列表中搜索属性
3Set<String> stringPropertyName();//返回此属性列表中的键集,其中该键及其对应值是字符串

5、示例演示1

package com.shan;
import java.util.Properties;
import java.util.Set;

/**需求:Properties集合的设置和获取演示
 * 
 * @param args
 */
public class Demo22 {
    public static void main(String[] args) {
        setAndGet();

    }
    public static void setAndGet()
    {
        Properties prop=new Properties();
        prop.setProperty("zhangsan", "21");
        prop.setProperty("lisi", "22");
        prop.setProperty("wangwu", "23");
        prop.setProperty("zhaoliu", "24");


        String value=prop.getProperty("wangwu");
        System.out.println(value);
        prop.setProperty("wangwu", "30");       
        Set<String> names=prop.stringPropertyNames();
        for(String s:names)
        {
            System.out.println(s+"::"+prop.getProperty(s));
        }
    }

}

示例演示2:如何将流中的数据存储到集合中?

package com.shan;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * 需求:如何将流中的数据存储到集合中?  
 * 例:将info.txt中的键值数据存到集合中进行操作
 * @param args
 */
public class Demo23 {
    public static void main(String[] args) {
        method();

    }
    public static void method()
    {
        BufferedReader bufr=null;
        String line=null;
        try 
        {
             bufr=new BufferedReader(new FileReader("info.txt"));
             Properties prop=new Properties();
             while((line=bufr.readLine())!=null)
             {
                 String[] arr=line.split("=");
                 prop.setProperty(arr[0], arr[1]);
             }
             System.out.println(prop);
        } 
        catch (IOException e) 
        {
            throw new RuntimeException("读取失败!");            
        }
        finally
        {           
                try 
                {
                    if(bufr!=null)
                    bufr.close();
                } 
                catch (IOException e) 
                {
                    throw new RuntimeException("关闭失败!");                    
                }
        }
    }

}

示例演示3:获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示,并不要再运行程序。

package com.shan;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * 需求:获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示,并不要再运行程序。
 * 
 * 思路:1、定义一个计数器,让程序即使结束,该计数器的值也存在,下次程序启动先加载计数器的值并加1后再重新存储起来。
 *     2、建立一个配置文件,用于记录该软件的使用次数
 *     3、该配置文件使用键值对的形式,这样便于阅读数据并操作数据
 *     4、键值对数据是Map集合,数据是以文件形式存储,使用io技术。
 *     5、Map+io---->Properties,配置文件可以实现应用程序数据的共享
 * @param args
 */
public class Demo24 {
    public static void main(String[] args) throws IOException {
        Properties prop=new Properties();
        File file=new File("count.properties");
        if(!file.exists())
            file.createNewFile();
        FileInputStream fis=new FileInputStream(file);
        prop.load(fis);
        int count=0;
        String value=prop.getProperty("time");
        if(value!=null)
        {
            count=Integer.parseInt(value);
            if(count>=5)
            {
                System.out.println("您好,使用次数已到,请注册!");
                return;
            }
        }
        count++;
        prop.setProperty("time", "count");
        FileOutputStream  fos=new FileOutputStream(file);
        prop.store(fos, "");
        fos.close();
        fis.close();

    }

}

三、 打印流(可以直接操作输入流和文件。)

1、 字符打印流:PrintWriter
2、 字节打印流:PrintStream(注意:PrintStream永远不会抛出IOException。)
3、 PrintStream构造函数可以接收的类型

1)  file对象
2)  字符串路径
3)  字节输出流   OutputStream

4、 PrintWriter构造函数可以接收的类型

1) file对象
2)字符串路径
3)字节输出流   OutputStream
4)字符输出流   Writer

5、 示例演示:把从键盘录入的数据打印到文件中

package com.shan;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;


/**
 * 需求:把从键盘录入的数据打印到文件中
 * @param args
 */
public class Demo25 {
    public static void main(String[] args) throws IOException {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw=new PrintWriter(new FileWriter("a.txt"),true);
        String line=null;
        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            pw.println(line.toUpperCase());
        }
        pw.close();
        bufr.close();
    }
}

四、 序列流(合并流):将多个流进行合并
1、SequenceInputStream:对多个流进行合并。

2、示例演示:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中。

package com.shan;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

/**需求:将1.txt、2.txt、3、txt文件中的数据合并到一个文件中。
 * @param args
 */
public class Demo26 {

    public static void main(String[] args) throws IOException {
        Vector<FileInputStream> v=new Vector<FileInputStream>();
        v.add(new FileInputStream("d:\\1.txt"));
        v.add(new FileInputStream("d:\\2.txt"));
        v.add(new FileInputStream("d:\\3.txt"));
        Enumeration<FileInputStream>  en=v.elements();
        SequenceInputStream  sis=new SequenceInputStream(en);
        FileOutputStream fos=new  FileOutputStream("d:\\4.txt");
        byte[] buf=new byte[1024];
        int len=0;
        while((len=sis.read(buf))!=-1);
        {
            fos.write(buf, 0, len);
            fos.close();
            sis.close();
        }
    }
}

五、 切割文件(文件切割器、文件合并器)

1、文件切割器演示

package com.shan;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**需求:将1.jpg文件切割成几个部分
 * @param args
 */
public class Demo28 {
    public static void main(String[] args) throws IOException 
    {
        splitFile();

    }
    public static void splitFile() throws IOException
    {
        FileInputStream  fis=new FileInputStream ("1.jpg");
        FileOutputStream fos=null;
        byte[] buf=new byte[1024*1024];
        int len=0;
        int count=0;
        while((len=fis.read(buf))!=-1)
        {
            fos=new FileOutputStream((count)+".part");
            fos.write(buf, 0, len);
            fos.flush();
        }
        fos.close();
        fis.close();

    }

}

2、文件合并器演示

package com.shan;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;

/**需求:将0.part文件合并成原来的1.jpg文件
 * @param args
 */
public class Demo29 {
    public static void main(String[] args) throws IOException 
    {
         ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
         for(int x = 0; x <= 3; x++)
         {
             al.add( new FileInputStream(x+ ".part" ));
         }

        final Iterator<FileInputStream> it = al.iterator();     

         Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
         {
             public boolean hasMoreElements()
             {
                 return it.hasNext();            
             }      
             public FileInputStream nextElement()
             {
                 return it.next();
             }
         };    //因为是匿名内部类,所以Iterator要用final来修饰

         SequenceInputStream sis = new SequenceInputStream(en);

         FileOutputStream fos = new FileOutputStream("3.jpg" );

         byte[] buf = new byte[1024];

         int len = 0;

         while((len = sis.read(buf)) != -1)
         {
             fos.write(buf,0,len);
         }

             fos.close();
             sis.close();
         }

}

六、 对象的序列化(对象流)

1、 ObjectInputStream与ObjectOutputStream

2、 它的强大之处就是可以将java中的对象写到文件中,也能把对象从文件中还原出来。

3、 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制。

4、 反序列化:用ObjectInputStream类基读取本类型数据或对象的机制。

5、 被序列化的对象所对应的类必须实现Serializable接口,Serializable接口并没有方法,仅作为标记,用来表示实现接口的类可以用于序列化

6、 注意:static或transient修饰的属性不会被序列化。

7、 示例演示:把Person对象序列化

import java.io.Serializable;
public class Person implements  Serializable
{
    String name;
    int age;
    static String country="cn";
    Person(String name,int age,String country)
    {
        this.name=name;
        this.age=age;
        this.country=country;       
    }
    public String toString()
    {
        return name+"..."+age+"..."+country;
    }   
}


package com.shan;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**需求:把Person对象序列化       ObjectOutputStream
 * @param args
 */
public class Demo31 {
public static void main(String[] args) throws IOException,ClassNotFoundException 
{

        readObj();
        writeObj();

    }
    public static void readObj() throws IOException,ClassNotFoundException

    ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
        Person p=(Person)ois.readObject();//读取对象,并转换类型
        System.out.println(p);
        ois.close();
    }
    public static void writeObj() throws IOException
    {
        ObjectOutputStream oos=new ObjectOutputStream(newFileOutputStream("obj.txt"));
        oos.writeObject(new Person("lisi",50,"kr"));//country被static修饰了,不能被序列化,所以只能打印出原有的值“cn”
        oos.close();
    }
}

七、 管道流:(PipedInputStream和PipedOutputStream)
1、 输入输出可以直接进行连接,通过结合线程使用
2、 方法:

1)  PipedInputStream():创建尚未连接的PipedInputStream,需要调用void connect(PipedOutputStream src)方法,使此管道输入流连接到管道输出流。
2)  使用构造方法使输入和输出相连接。
PipedInputStream(PipedOutputStream src);创建PipedInputStream,使其连接到管道输出流src

3、 示例演示:管道流的输入流和输出流的连接演示

package com.shan;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
 * @param args
 */
public class Demo32 {

    public static void main(String[] args) throws IOException
    {
        PipedInputStream in=new PipedInputStream();
        PipedOutputStream out=new PipedOutputStream();
        in.connect(out);
        Read r=new Read(in);
        Write w=new Write(out);     
        new Thread(r).start();
        new Thread(w).start();

    }   
}
class Read implements Runnable
{
    private PipedInputStream in;
    Read(PipedInputStream in)
    {
        this.in=in;
    }
    public void run()
    {
        try
        {
            byte[] buf=new byte[1024];
            int len=0;
            String s=new String(buf,0,len);
            System.out.println(s);
            in.close();
        }
        catch(IOException e)
        {
            throw new RuntimeException("管道读取流失败!");
        }
    }
}
class Write implements Runnable
{
    private PipedOutputStream  out;
    Write(PipedOutputStream  out)
    {
        this.out=out;
    }
    public void run()
    {
        try
        {
            out.write("管道来了".getBytes());
            out.close();
        }
        catch(IOException e)
        {
            throw new RuntimeException("管道输出流失败!");
        }
    }
}

八、 随机访问文件:RandomAccessFile

1、随机访问文件,自身具备读写的方法。
2、通过skipBytes(int x),seek(int x)等方法来达到随机访问。
3、特点:

1)该对象即能读,又能写。
2)该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素。
3)可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
4)其实该对象就是将字节输入流和输出流进行了封装。
5)该对象的源或者目的只能是文件。通过构造函数就可以看出。

九、 转换流的字符编码
1、 字符流的出现是为了方便操作字符,更重要的是加入了编码转换。
2、 通过子类转换流来完成。InputStreamReader 和 OutputStreamWriter
3、 示例演示:

package com.shan;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


/**
 * @param args
 */
public class Demo33 {
    public static void main(String[] args) throws IOException
    {
        writeText();
        readText();

    }
    public static void readText() throws IOException
    {
        InputStreamReader isr=new InputStreamReader(newFileInputStream("utf.txt"),"utf-8");
        char[] buf=new char[10];
        int len=isr.read(buf);
        String str=new String(buf,0,len);
        System.out.println(str);
        isr.close();
    }
    public static void writeText() throws IOException
    {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("utf.txt"),"utf-8");
        osw.write("您好");
        osw.close();
    }
}

十、 字符编码
1、 默认编码形式是GBK
2、 编码:字符串变成字节数组 String–byte[]
解码:字节数组编程字符串 byte[]–String
3、 方法:
String(byte[] byte,String charsetName);
getBytes(String charsetName);

4、 示例演示:

package com.shan;
import java.io.IOException;
import java.util.Arrays;
/**进行编码操作
 * @param args
 */
public class Demo34 {
    public static void main(String[] args) throws IOException {
        String s="你好";
        byte[] b1=s.getBytes("utf-8");
        System.out.println(Arrays.toString(b1));
        String s1=new String(b1,"utf-8");
        System.out.println("s1="+s1);


    }

}

5、 有时候,会遇到这么一个情况:用GBK进行了编码,可解码时用iso8859-1进行了解码,那么,这时该怎么办呢?
解决思路:将iso8859-1解码后的数组进行再一次的编码(用iso8859-1进行解码,编码后,再用GBK进行解码就可解决这个问题)

代码演示:

package com.shan;
import java.io.IOException;
import java.util.Arrays;

/**需求:用GBK进行了编码,可解码时用iso8859-1进行了解码,那么,这时该怎么办呢?
 * 解决思路:将iso8859-1解码后的数组进行再一次的编码(用iso8859-1进行解码,编码后,再用GBK进行解码就可解决这个问题)
 * @param args
 */
public class Demo35 {
    public static void main(String[] args) throws IOException {

        String s="你好";
        byte[] b1=s.getBytes("GBK");
        System.out.println(Arrays.toString(b1)); //把编码后的字节数组打印一下
        String s1=new String(b1,"ISO8859-1");
        System.out.println("s1="+s1);
        //对s1进行is08859-1编码
        byte[] b2=s1.getBytes("ISO8859-1");
        System.out.println(Arrays.toString(b2)); //把编码后的字节数组打印一下
        String s2=new String(b2,"GBK");
        System.out.println("s2="+s2);
    }

}


——- android培训java培训、期待与您交流! ———-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值