JavaSE基础——(22)IO流&其他流&Properties

目录

一、序列流

二、内存输出流

2.1内存输出流概述与使用

2.2内存输出流之面试题

三、随机访问流

四、对象操作流

4.1对象操作流概述与使用

4.2利用集合进行对象读写优化

五、数据输入输出流

六、打印流

七、标准输入输出流

7.1标准输入输出流概述与使用

7.2修改标准输入输出流读写文件数据

7.3修改标准输入输出流拷贝图片

八、两种方式的键盘录入

8.1 BufferedReader

8.2 Scanner

九、Properties

9.1 Properties概述及基本使用

9.2 Properties特殊功能

9.3 配置文件的加载和保存


 

一、序列流

序列流可以把多个字节输入流整合成一个,

它从一个有序的输入流集合开始,从第一个读取到文件的结尾,然后从第二个文件读取,

依此类推,直到最后一个输入流达到文件的结尾。

其整合两个输入流的方式如下,

SequenceInputStream(InputStream s1, InputStream s2)

我们来看看具体如何使用的吧,

        //将两个文件的内容合并写到一个文本文件中
        FileInputStream fis1=new FileInputStream("data.txt");
        FileInputStream fis2=new FileInputStream("data2.txt");
        SequenceInputStream sis=new SequenceInputStream(fis1,fis2);
        FileOutputStream fos=new FileOutputStream("dataOutput.txt");

        int c;
        while((c=sis.read())!=-1){
            fos.write(c);
        }

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

 

二、内存输出流

2.1内存输出流概述与使用

该输出流可以向内存中写数据,把内存当作一个缓冲区, 写出之后可以一次获取所有的数据,

在使用时会创建对象ByteArrayOutputStream,该类中的数据被写入了一个byte数组,缓冲区会随着数据的写入而自动增长,

写出数据为write(int)或者write(byte[]),获取数据为toByteArray(),

之前我们使用FileInputStream读取中文的时候出现了乱码问题,这个问题我们也可以用内存输出流来解决,

        FileInputStream fis=new FileInputStream("data.txt");
        ByteArrayOutputStream baos=new ByteArrayOutputStream();//在内存中创建了字节数组缓冲区

        int b;
        while((b=fis.read())!=-1){
            baos.write(b);//将文件数据写入缓冲区
        }
        byte arr[]=baos.toByteArray();//将缓冲区数据获取到字节数组中
        System.out.println(new String(arr));

        fis.close();
        //注意这里不用关闭ByteArrayOutputStream的流,该流关闭操作无效

我们可以看到中文读取的时候已经可以正确显示了, 

 

2.2内存输出流之面试题

要求定义一个文件输出流,调用read(byte b[])的方法,将data.txt文件中的内容打印出来(byte数组大小限制为5)。

        FileInputStream fis=new FileInputStream("data.txt");
        ByteArrayOutputStream baos=new ByteArrayOutputStream();

        byte arr[]=new byte[5];
        int len;
        while((len=fis.read(arr))!=-1){
            baos.write(arr,0,len);//将文件数据写入缓冲区
        }
        System.out.println(baos);

        fis.close();

 

三、随机访问流

RandomAccessFile类不属于流,是Object类的子类,但它融合了InputStream和OutputStream的功能,

支持对随机访问文件的读取和写入,该类有两个构造函数,

RandomAccessFile(File file, String mode)//创建File文件的随机访问文件流,用于读取和写入
RandomAccessFile(String name, String mode)创建指定名称name的随机访问文件流,用于读取和写入
//其中mode包括:"r",只读、"rw"读取和写入、"rws"读取和写入并且同步更新
        RandomAccessFile raf=new RandomAccessFile("data.txt","rw");
        System.out.println(raf.readLine());
        raf.seek(20);//将指针移到索引为20的地方
        raf.write("You love java.".getBytes());//写入字符串
        raf.close();

在指定位置进行读写的好处是可以进行多线程的下载,可以将整个文件按照一定字节数分块,

然后分块用多线程下载最后将字节写到对应的位置就可以了。

 

四、对象操作流

4.1对象操作流概述与使用

ObjectInputStream和ObjectOutputStream是操作对象进行读取和写入的,

主要用到的方法是writeObject和readObject,我们来看看具体如何使用,

        Student s1=new Student("测试1",21);
        Student s2=new Student("测试2",22);

        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("StudentData.txt"));
        oos.writeObject(s1);
        oos.writeObject(s2);
        oos.close();

        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("StudentData.txt"));
        Student stu1=(Student)ois.readObject();
        Student stu2=(Student)ois.readObject();
        System.out.println(stu1);
        System.out.println(stu2);
        ois.close();

需要注意的是我们要在自定义的类对象中实现一下Serializable接口,实现序列化,否则会抛出NotSerializableException异常,

class Student implements Serializable

然后我们看看写入对象数据然后紧接着读取输出的结果,

 

4.2利用集合进行对象读写优化

我们发现,如果自定义对象比较多,那么存储的时候就会比较麻烦,

一般这个时候我们会先将自定义的对象装到集合对象里面,然后将集合对象写入到文件中,

        Student s1=new Student("测试1",21);
        Student s2=new Student("测试2",22);
        Student s3=new Student("测试3",23);
        ArrayList<Student> list=new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);

        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("StudentData.txt"));
        oos.writeObject(list);
        oos.close();

        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("StudentData.txt"));
        ArrayList<Student> readlist=(ArrayList<Student>)ois.readObject();
        for (Student stu: readlist) {
            System.out.println(stu);
        }
        ois.close();

 

五、数据输入输出流

DataInputStream和DataOutputStream可以按照基本数据类型大小读写数据,

例如按照Long类型大小写出一个数字,写出时该数据占8个字节,读取的时候也按照Long类型读取,一次读取8个字节,

        DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
        dos.writeInt(10086);
        dos.writeBytes("java");
        dos.writeChar(97);
        dos.close();

        DataInputStream dis=new DataInputStream((new FileInputStream("data.txt")));
        System.out.println(dis.readInt());
        byte arr[]=new byte[4];
        dis.readFully(arr);
        for (int i = 0; i < 4; i++) {
            System.out.print((char)arr[i]);
        }
        System.out.println();
        System.out.println(dis.readChar());
        dis.close();

 

六、打印流

打印流可以很方便的将对象的toString()结果输出,并且自动加上换行,而且可以使用自动刷出的模式,

System.out就是一个PrintStream,默认向控制台输出信息,PrintStream是打印字节流,PrintWriter是打印字符流。

        PrintStream ps=System.out;
        ps.println(100);//底层通过Integer.toString()将100转换为字符串输出
        ps.println("java");

        Student stu=new Student("测试",20);//打印引用数据类型,使用toString()方法(如果为null则打印null)
        ps.println(stu);

我们还可以使用PrintWriter将字符流写入文件,

        PrintWriter pw=new PrintWriter("data.txt");
        pw.println(97);//写数字97
        pw.write(97);//写字符a
        pw.close();

其中PrintWriter的构造函数有个autoFlush需要注意,

PrintWriter(OutputStream out, boolean autoFlush)//这里的autoFlush如果设置为true,那么边写入的时候会自动刷新内容到文件中,自动刷新只针对println操作,对write和print无效。

 

七、标准输入输出流

7.1标准输入输出流概述与使用

  • System.in是InputStream,标准输入流,默认可以从键盘读取字节数据
  • System.out是OutputStream,标准输出流,默认可以向控制台中输出字符和字节数据

正常使用标准输入输出流时不用执行close操作,但是如果关联到某个文件上了,则必须执行close操作,

        InputStream is=System.in;
        int x=is.read();//读取一个字节的数据
        System.out.println(x);
        is.close();

 

7.2修改标准输入输出流读写文件数据

我们还可以使用System.setIn和System.setOut方法改变标准输入流,从文件读取写入数据,

        System.setIn(new FileInputStream("data.txt"));//改变标准输入流
        System.setOut(new PrintStream("dataOutput.txt"));//改变标准输出流

        InputStream is=System.in;//获取标准的键盘输入流,默认指向键盘,改变后指向文件
        PrintStream ps=System.out;//获取标准的打印输出流,默认指向控制台,改变后指向文件

        int b;
        while((b=is.read())!=-1){
            ps.write((char)b);
        }

        is.close();
        ps.close();

 

7.3修改标准输入输出流拷贝图片

拷贝图片其实和前面一个差不多,只不过一个是文本文件,一个是图片文件。这里我们用byte数组来读效率高一点, 

        System.setIn(new FileInputStream("luffy.jpg"));//改变标准输入流
        System.setOut(new PrintStream("luffyCopy.jpg"));//改变标准输出流

        InputStream is=System.in;//获取标准的键盘输入流,默认指向键盘,改变后指向文件
        PrintStream ps=System.out;//获取标准的打印输出流,默认指向控制台,改变后指向文件

        byte arr[]=new byte[1024];
        int len;
        while((len=is.read(arr))!=-1){
            ps.write(arr,0,len);
        }

        is.close();
        ps.close();

可以看到图片被复制成功了, 

 

八、两种方式的键盘录入

8.1 BufferedReader

BufferedReader可以通过InputStreamReader将字节流的System.in转换为字符流,

然后构造出BufferedReader对象进行键盘录入,

        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str=br.readLine();
        System.out.println(str);
        br.close();

 

8.2 Scanner

Scanner读取键盘录入的功能更加强大,不仅可以读取字符串,还有其他基本类型数据。

        Scanner sc=new Scanner(System.in);
        String str=sc.nextLine();
        System.out.println(str);
        sc.close();
 

 

九、Properties

9.1 Properties概述及基本使用

Properties类主要用于读取Java的配置文件,

不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,

为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。

就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的,

它是Hashtable的子类,我们先用集合的方法来存储键值对元素,

        Properties prop=new Properties();
        prop.put("test",1);//使用集合的方法存储
        System.out.println(prop);

Properties类表示了一个持久的属性集,可以保存在流中或者从流中加载,

其属性列表中每个键对应的值都是一个字符串。

 

9.2 Properties特殊功能

public Object setProperty(String key,String value)//设置键值对
public String getProperty(String key)//根据键返回值
public Enumeration<String> stringPropertyNames()//返回属性列表中所有键的枚举

我们来看看实际如何使用这些方法,

        Properties prop=new Properties();
        prop.setProperty("name","peru");
        prop.setProperty("home","wuhan");
        prop.setProperty("tel","15912345678");

        Enumeration<String> en=(Enumeration<String>)prop.propertyNames();//获取所有键
        while(en.hasMoreElements()){
            String key=en.nextElement();//获取键
            String value=prop.getProperty(key);//根据键获取值
            System.out.println(key+"="+value);
        }

 

9.3 配置文件的加载和保存

我们现在想要将配置文件存储在硬盘上,而不是内存中,这里就需要用到Properties的load()和store()方法了,

void load(InputStream inStream)//从输入字节流读取属性列表(键和元素对)
void load(Reader reader)//从输入字符流读取属性列表(键和元素对)
void store(OutputStream out, String comments)//将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法加载到Properties表中的格式输出流
void store(Writer writer, String comments)//将此属性列表(键和元素对)写入此Properties表中,以适合使用load(Reader)方法的格式输出到输出字符流

我们来看看具体如何使用这两个方法,

        Properties prop=new Properties();
        
        //读取配置文件
        prop.load(new FileInputStream("config.properties"));
        System.out.println(prop);

        //修改配置文件
        prop.setProperty("home","beijing");
        prop.store(new FileOutputStream("config.properties"),"修改了家庭住址");//后面的参数comments为对配置文件的说明

我们可以先看到配置文件被正确读取出来了,

然后打开配置文件发现也被正确修改了信息,而且comments的信息也在文件中以注释的形式体现了,

如果什么也不想显示可以给comments赋值为null,同时显示的还有更改的时间,

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值