数据操作流

数据操作流:操作基本类型数据的流


(1)可以操作基本类型的数据
(2)流对象名称
DataInputStream
DataOutputStream

 1 /*
 2  * 读写基本数据类型的数据
 3  * 
 4  * 数据输入流:DataInputStream
 5  *             DataInputStream(InputStream in)
 6  * 数据输出流:DataOutputStream
 7  *             DataOutputStream(OutputStream out)
 8  *             
 9  */
10 public class DataStreamDemo {
11 
12     public static void main(String[] args) throws IOException {
13         //
14         write();
15         
16         //
17         read();
18         
19     }
20 
21     private static void read() throws IOException {
22         // DataOutputStream(OutputStream out)
23         //创建数据输入流
24         DataInputStream dis = new DataInputStream(new 
25                 FileInputStream("b.txt"));
26         
27         byte b = dis.readByte();
28         int i = dis.read();
29         char c = dis.readChar();
30         double d = dis.readDouble();
31         float f = dis.readFloat();
32         short s = dis.readShort();
33         long l = dis.readLong();
34         boolean bb = dis.readBoolean();
35         
36         System.out.println(b);
37         System.out.println(i);
38         System.out.println(c);
39         System.out.println(d);
40         System.out.println(f);
41         System.out.println(s);
42         System.out.println(l);
43         System.out.println(bb);
44     }
45 
46     private static void write() throws IOException {
47         // DataOutputStream(OutputStream out)
48         //创建数据输出流对象
49         DataOutputStream dos = new DataOutputStream(
50                 new FileOutputStream("a.txt"));
51         
52         //写数据
53         dos.writeByte(10);
54         dos.write(122);
55         dos.writeChar('b');
56         dos.writeDouble(13.68);
57         dos.writeFloat(11.23F);
58         dos.writeShort(1000);
59         dos.writeLong(100000);
60         dos.writeBoolean(false);
61         
62         //释放资源
63         dos.close();
64 
65     }
66 
67 }

3:内存操作流(理解)
(1)有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
(2)三种
A:ByteArrayInputStream

   ByteArrayOutputStream
B:CharArrayReader

   CharArrayWriter
C:StringReader

    StringWriter

 1 /*
 2  * 内存操作流:用于处理临时存储的信息,程序结束后数据就从内存中消失
 3  * 
 4  * 字节数组:ByteArrayInputStream
 5  *        ByteArrayOutputStream
 6  *        
 7  * 字符数据:CharArrayReader
 8  *        CharArrayWriter
 9  * 
10  * 字符串:StringReader
11  *      StringWriter
12  */
13 public class ByteArrayInputStreamDemo {
14 
15     public static void main(String[] args) throws IOException {
16         //写数据
17         //ByteArrayOutputStream
18         ByteArrayOutputStream baos = new ByteArrayOutputStream();
19         
20         //写数据
21         for(int x = 0; x < 10; x++){
22             baos.write(("hello" + x).getBytes());
23         }
24         //不需要释放资源
25         
26         
27         //public byte[] toByteArray()转换成自己数组再读取
28         byte[] bys = baos.toByteArray();
29         
30         //读数据
31         //ByteArrayInputStream
32         ByteArrayInputStream bais = new ByteArrayInputStream(bys);
33         
34         int by = 0;
35         while((by = bais.read()) != -1){
36             System.out.println((char)by);
37         }
38         
39     }
40 }

4:打印流
(1)字节打印流,字符打印流
(2)特点:
A:只操作目的地,不操作数据源
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
D:可以直接操作文件
问题:哪些流可以直接操作文件呢?
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
(3)复制文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);

String line = null;
while((line=br.readLine())!=null) {
pw.println(line);
}

pw.close();
br.close();

 1 /*
 2  * 将a.txt中的内容复制到b.txt
 3  * 
 4  * 数据源:a.txt   读取数据      FileReader  BufferedReader
 5  * 目的地:b.txt   写出数据      FileWriter  BufferedWriter  PrintWriter
 6  */
 7 public class PrintWriterDemo {
 8 
 9     public static void main(String[] args) throws IOException {
10         //以前的版本实现
11         //封装数据源
12 //        BufferedReader br = new BufferedReader(new
13 //                FileReader("a.txt"));
14 //        //封装目的地
15 //        BufferedWriter bw = new BufferedWriter(new 
16 //                FileWriter("b.txt"));
17 //        
18 //        //读数据
19 //        String line = null;
20 //        while((line = br.readLine()) != null){
21 //            bw.write(line);
22 //            bw.newLine();
23 //            bw.flush();
24 //        }
25 //        
26 //        bw.close();
27 //        br.close();
28         
29         
30         //改进版本  打印流
31         //封装数据源
32         BufferedReader br = new BufferedReader(new
33                 FileReader("a.txt"));
34         
35         //封装目的地
36         PrintWriter pw = new PrintWriter(new FileWriter("b.txt"), true);//启用自动刷新功能
37         String line = null;
38         while((line = br.readLine()) != null){
39             pw.println();
40         }
41         pw.close();
42         br.close();
43     }
44 }
 1 public class PrintWriterDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //作为Writer的子类使用
 5         PrintWriter pw = new PrintWriter("a.txt");
 6         
 7         pw.write("hello");
 8         pw.write("java");
 9         
10         pw.close();
11     }
12 }
 1 /*
 2  * 操作任意类型的数据
 3  *    print()
 4  *    println()
 5  * 启用自动刷新
 6  *    PrintWriter pw = new PrintWriter(new FileWriter("b.txt"), true);
 7  *    这时应该调用println()方法才可以实现刷新和自动换行
 8  *    
 9  *    println()等价于bw.write();
10  *                 bw.newLine();
11  *                 bw.flush();
12  */
13 public class PrintWriterDemo2 {
14     public static void main(String[] args) throws IOException {
15         //创建打印对象
16         //PrintWriter pw = new PrintWriter("a.txt");
17         //启用自动刷新
18         PrintWriter pw = new PrintWriter(new FileWriter("b.txt"), true);
19         //这时的Write()是不能实现任意类型的
20         //使用print()
21         //pw.print(true);
22         //pw.print("hello");
23         //pw.print(100);
24         
25         pw.println("hello");
26         pw.println(100);
27         pw.println(true);
28         
29         pw.close();
30     }
31 }


5:标准输入输出流
(1)System类下面有这样的两个字段
in 标准输入流
out 标准输出流


(2)三种键盘录入方式
A:main方法的args接收参数
B:System.in通过BufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
C:Scanner
Scanner sc = new Scanner(System.in);


(3)输出语句的原理和如何使用字符流输出数据
A:原理
System.out.println("helloworld");
PrintStream ps = System.out;
ps.println("helloworld");
B:把System.out用字符缓冲流包装一下使用
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

6:随机访问流
(1)可以按照文件指针的位置写数据和读数据。
(2)案例:
A:写数据
B:读数据
C:获取和改变文件指针的位置

7:合并流
(1)把多个输入流的数据写到一个输出流中。
(2)构造方法:
A:SequenceInputStream(InputStream s1, InputStream s2)
B:SequenceInputStream(Enumeration<? extends InputStream> e)

8:序列化流
(1)可以把对象写入文本文件或者在网络中传输
(2)如何实现序列化呢?
让被序列化的对象所属类实现序列化接口。
该接口是一个标记接口。没有功能需要实现。
(3)注意问题:
把数据写到文件后,在去修改类会产生一个问题。
如何解决该问题呢?
在类文件中,给出一个固定的序列化id值。
而且,这样也可以解决黄色警告线问题
(4)面试题:
什么时候序列化?
如何实现序列化?
什么是反序列化?

 1 /*
 2  * 序列化流:把对象按照流一样的方式存入文本文件或者在网络上传输。对象--流数据
 3  *        ObjectOutputStream
 4  * 反序列化:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据--对象
 5  *        ObjectInputStream
 6  */
 7 public class ObjectStreamDemo {
 8     public static void main(String[] args) throws IOException, ClassNotFoundException {
 9         //对对象进行序列化,首先自定义一个类Person
10         
11         //序列化数据  即就是将对象写到文本文件
12         write();
13         
14         read();
15     }
16 
17     private static void read() throws IOException, IOException, ClassNotFoundException {
18         // 创建反序列化对象
19         ObjectInputStream ois = new ObjectInputStream(new 
20                 FileInputStream("b.txt"));
21         
22         //还原对象
23         Object obj = ois.readObject();
24         
25         //释放资源
26         ois.close();
27         
28         //输出对象
29         System.out.println(obj);
30     }
31 
32     private static void write() throws IOException, IOException {
33         //创建序列化流对象
34         ObjectOutputStream oos = new ObjectOutputStream(
35                 new FileOutputStream("a.txt"));
36         //创建对象
37         Person p = new Person("张三", 20);
38         
39         oos.writeObject(p);
40         
41         //释放资源
42         oos.close();
43         
44     }
45 
46 }
 1 //没有任何方法  这种没有方法的接口称为标记接口
 2 public class Person implements Serializable{
 3     private static final long serialVersionUID = 1L;
 4     private String name;
 5     private String age;
 6     
 7     
 8     
 9     public Person() {
10         super();
11     }
12 
13 
14 
15     public Person(String name, int age) {
16         super();
17         this.name = name;
18         this.age = age;
19     }
20 
21 
22 
23     public String getName() {
24         return name;
25     }
26 
27 
28 
29     public void setName(String name) {
30         this.name = name;
31     }
32 
33 
34 
35     public String getAge() {
36         return age;
37     }
38 
39 
40 
41     public void setAge(String age) {
42         this.age = age;
43     }
44 
45 
46 
47     @Override
48     public String toString() {
49         return "Person [name=" + name + ", age=" + age + "]";
50     }
51 
52 }

 注意:有时候一个类中有很多成员变量,有些是不需要被序列化的,这时采用transient关键字声明不需要被序列化的成员变量

 1 public class Person implements Serializable{
 2 
 3     private static final long serialVersionUID = 1L;
 4     
 5     private String name;
 6     //private String age;
 7     private transient int age;
 8     //int age;
 9     
10     public Person() {
11         super();
12     }
13 
14 
15 
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21 
22 
23 
24     public String getName() {
25         return name;
26     }
27 
28 
29 
30     public void setName(String name) {
31         this.name = name;
32     }
33 
34 
35 
36     public int getAge() {
37         return age;
38     }
39 
40 
41 
42     public void setAge(int age) {
43         this.age = age;
44     }
45 
46 
47 
48     @Override
49     public String toString() {
50         return "Person [name=" + name + ", age=" + age + "]";
51     }
52 
53 }

9:Properties
(1)是一个集合类,Hashtable的子类

 1 /*
 2  * Properties:属性集合类,是可以和IO流相结合使用的集合类
 3  * Properties可以保存在流中和从流中加载,属性列表中每个键及其对应值都是一个字符串
 4  * 
 5  * 是Hashtable的子类,是一个Map集合
 6  */
 7 public class PropertiesDemo {
 8 
 9     public static void main(String[] args) {
10         Properties prop = new Properties();
11         
12         //添加元素
13         prop.put("ob001", "hello");
14         prop.put("ob002", "world");
15         
16         //遍历集合
17         Set<Object> set = prop.keySet();
18         for(Object key : set){
19             Object value = prop.get(key);
20             System.out.println(key + "----" + value);
21         }
22     
23     }
24 }


(2)特有功能
A:public Object setProperty(String key,String value)
B:public String getProperty(String key)
C:public Set<String> stringPropertyNames()

 1 /*
 2  * 特殊功能
 3  * public Object setProperty(String key,String value) 添加元素
 4  * public String getProperty(String key)  获取元素
 5  * public Set<String> stringPropertyNames() 获取所有键的集合
 6  */
 7 public class PropertiesDemo2 {
 8     public static void main(String[] args) {
 9         //创建集合对象
10         Properties prop = new Properties();
11         
12         //添加元素  只能添加字符串
13         prop.setProperty("张三", "20");
14         prop.setProperty("李四", "30");
15         prop.setProperty("王五", "50");
16         
17         
18         //public Set<String> stringPropertyNames() 获取所有键的集合
19         Set<String> set = prop.stringPropertyNames();
20         for(String key : set){
21             String value = prop.getProperty(key);
22             System.out.println(key + "----" + value);
23         }
24     }
25 
26 }


(3)和IO流结合的方法
把键值对形式的文本文件内容加载到集合中
public void load(Reader reader)
public void load(InputStream inStream)

把集合中的数据存储到文本文件中
public void store(Writer writer,String comments)
public void store(OutputStream out,String comments)

 1 /*
 2  * public void load(Reader reader) 将文件中的数据读取到集合中
 3  * public void store(Writer writer, String comments) 把集合中的数据存储到文件
 4  * 
 5  * 这里的集合必须是Properties集合
 6  */
 7 public class PropertiesDemo3 {
 8 
 9     public static void main(String[] args) throws Exception {
10         load();
11         store();
12     }
13 
14     private static void store() throws Exception {
15         //创建集合
16         Properties prop = new Properties();
17         //集合里面添加数据
18         prop.setProperty("张三", "24");
19         prop.setProperty("李四", "34");
20         prop.setProperty("王五", "26");
21         
22         //public void store(Writer writer, String comments) 把集合中的数据存储到文件
23         Writer w = new FileWriter("a.txt");
24         prop.store(w, "hello");//"hello"对文件的描述
25         w.close();
26         
27     }
28 
29     private static void load() throws IOException {
30         //创建集合
31         Properties prop = new Properties();
32         
33         // public void load(Reader reader) 将文件中的数据读取到集合中
34         //注意:这里读取的文件的数据必须是键值对形式
35         /*
36          * a.txt
37          * zhangsan=20
38          * wangwu=30
39          * lisi=40
40          */
41                 
42         Reader r = new FileReader("a.txt");
43         prop.load(r);
44         r.close();
45     }
46 }


(4)案例:
A:根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100

 1 /*
 2  * 有一个a.txt文件  不知道里面的键值对形式
 3  * 通程序判断是否含有"zhangsan"这样的键存在,如果有将其改变为"001"
 4  * 
 5  * 将文件中的数据加载到集合中
 6  * 遍历集合获取到每一个键
 7  * 判断键是否有"zhangsan"的,如果有就修改其值为"001"
 8  * 将集合中的数据重新存储到文件
 9  */
10 public class PropertiesTest {
11 
12     public static void main(String[] args) throws IOException {
13         //将文件中的数据加载到集合中
14         Properties prop = new Properties();
15         Reader r = new FileReader(".txt");
16         prop.load(r);
17         r.close();
18         
19         //遍历集合获取到每一个键
20         Set<String> set = prop.stringPropertyNames();
21         for(String key : set){
22             //判断键是否有"zhangsan"的,如果有就修改其值为"001"
23             if("zhangsan".equals(key)){
24                 prop.setProperty(key, "001");
25                 break;
26             }
27         }
28         
29         //将集合中的数据重新存储到文件
30         Writer w= new FileWriter("b.txt");
31         prop.store(w, null);
32         w.close();
33     }
34 }



 

原文地址:https://www.cnblogs.com/lyywj170403/p/9296999.html