黑马程序员——java基础—IO流(二)
来源:互联网 发布:万能扫描仪软件免费版 编辑:程序博客网 时间:2024/05/05 21:21
——- android培训、java培训、期待与您交流! ———-
打印流概述:
字节流打印流 PrintStream
字符流打印流 PrintWriter
打印流的特点:
A:只有写数据,没有读取数据。只能操作目的地,不能操作数据源。
B:可以操作任意类型的数据。
C:如果启动了自动刷新,能够自动刷新。
D:可以操作文件的流。
那些流对象是可以直接操作文本文件的呢?
FileInputStream
FileOutputStream
FileReader
FileWriter
printStream
printWriter
看API,查流对象的构造方法,如果同时有File类型和String类型的参数,一般来说就是可以直接操作文件的。
流对象:
基本流:就是能直接读写文件
高级流:在基本流基础上提供了一些其他功能;
1. 可以操作任意类型的数据:
Print()
Pritln()
2. 启动自动刷新:
printWriter pw = new PrintWriter(new FileWriter(“a.txt:” ,true)
还是调用println()的方法才可以;
这个时候不仅仅自动刷新了,还实现了数据的换行;
Println() 等价于:
Write();
newLine();
flush();
打印流复制文本文件;
// 以前的版本 // 封装数据源 // BufferedReader br = new BufferedReader(newFileReader( // "DataStreamDemo.java")); // // 封装目的地 // BufferedWriter bw = new BufferedWriter(newFileWriter("Copy.java")); // // String line = null; // while ((line = br.readLine()) != null) { // bw.write(line); // bw.newLine(); // bw.flush(); // } // // bw.close(); // br.close(); // 打印流的改进版 // 封装数据源 BufferedReader br = new BufferedReader(new FileReader( "DataStreamDemo.java")); // 封装目的地 PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true); String line = null; while((line=br.readLine())!=null){ pw.println(line); } pw.close(); br.close(); }
IO流标准输入输出流概述和输出语句的本质:
System类中的两个成员变量:
Public static final InputStream in “标准“输入流;
Public static final PrintStream out “标准”输出流;
inputStream is= System.in;
PrintStream ps= System.out;
System.in 标准输入流,是从键盘获取数据的
键盘录入数据:
A:main方法的args接收参数;
B:Scanner()
Scanner sc = newScanner(System.in);
String s = sc.nextLine();
Int x= sc.nextInt();
C:通过字符缓冲流包装标准输入流实现;
BuffereReader br = new BufferedReader(new InputStreamReader(system.in);
public static void main(String[] args) throwsIOException { // //获取标准输入流 // InputStream is = System.in; // //我要一次获取一行行不行呢? // //行。 // //怎么实现呢? // //要想实现,首先你得知道一次读取一行数据的方法是哪个呢? // //readLine() // //而这个方法在哪个类中呢? // //BufferedReader // //所以,你这次应该创建BufferedReader的对象,但是底层还是的使用标准输入流 // // BufferedReader br = new BufferedReader(is); // //按照我们的推想,现在应该可以了,但是却报错了 // //原因是:字符缓冲流只能针对字符流操作,而你现在是字节流,所以不能是用? // //那么,我还就想使用了,请大家给我一个解决方案? // //把字节流转换为字符流,然后在通过字符缓冲流操作 // InputStreamReader isr = newInputStreamReader(is); // BufferedReader br= new BufferedReader(isr); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入一个字符串:"); String line = br.readLine(); System.out.println("你输入的字符串是:" + line); System.out.println("请输入一个整数:"); // int i = Integer.parseInt(br.readLine()); line = br.readLine(); int i = Integer.parseInt(line); System.out.println("你输入的整数是:" + i); }
随机访问流:
RandomAccessFile类不属于流,是Object类的子类。
但它融合了InputStream和OutputStream的功能。
支持对随机访问文件的读取和写入;
PublicRandAccessFile(String name,String mode)
第一个参数是文件路径,
第二个参数是操作文件的模式;
private static void read() throws IOException { // 创建随机访问流对象 RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw"); int i = raf.readInt(); System.out.println(i); // 该文件指针可以通过 getFilePointer方法读取,并通过 seek 方法设置。 System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); char ch = raf.readChar(); System.out.println(ch); System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); String s = raf.readUTF(); System.out.println(s); System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); // 我不想重头开始了,我就要读取a,怎么办呢? raf.seek(4); ch = raf.readChar(); System.out.println(ch); } private static void write() throws IOException { // 创建随机访问流对象 RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw"); // 怎么玩呢? raf.writeInt(100); raf.writeChar('a'); raf.writeUTF("中国"); raf.close(); }}
合并流:
SequencelnputStream概述:
SequenceInputStream类可以将多个输入流串流在一起,合并为一个输入流,因此,该流也称为合并流;
SequenceInputStream的构造方法:
SenquenceInputStream(InputStream s1 , InputStream s2)
SequenceInputStream(Enumeration <? ExtendsInputStream>e)
1.txt + b.txt = c.txt;
InputStream s1 = new FileInputStream("a.txt"); InputStream s2 = new FileInputStream("b.txt"); SequenceInputStream sins = new SequenceInputStream(s1,s2); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c.txt")); //如何读写 byte[] buy = new byte[1024]; int len = 0; while((len = sins.read(buy))!= -1 ){ bos.write(buy,0 ,len); } bos.close(); sins.close(); }
合并流读取多个文件的内容复制到一个文件中;
SequenceInputStream (Enumeration e)
通过简单的回顾我们知道了Enumeration是 Vector中的一个方法的返回值类型;
Enumeration<E> elements()
Vector<InputStream> v = new Vector<InputStream>(); InputStream s1 = new FileInputStream("a.txt"); InputStream s2 = new FileInputStream("b.txt"); InputStream s3 = new FileInputStream("c.txt"); v.add(s1); v.add(s2); v.add(s3); Enumeration<InputStream> en =v.elements(); SequenceInputStream sins = new SequenceInputStream(en); BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("c.txt")); //读写文件件; byte[] bys = new byte[1024]; int len = 0; while((len= sins.read(bys)) != -1){ bos.write(bys,0 ,len); } bos.close(); sins.close(); }
序列化流:
序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象——流数据(ObjectOutputStream)
反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据———(ObjectInputStream)
Public final void writeObject(Object obj);
NotSerializableException没有序列化接口接口;
类通过实现java.io.Serializable接口以启动其序列化功能,未实现此接口的类将无法使其任何状态序列化或反序列化;
该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口;
public static void main(String[] args) throws IOException,ClassNotFoundException { //由于我们要对对象进行序列化,所以我们先定义一个类 //序列化数据其实就是把对象写到文本文件;write();read(); } private static void read() throws IOException, ClassNotFoundException { // TODOAuto-generated method stub //创建反序列化对象ObjectInputStreamois = new ObjectInputStream(new FileInputStream("oos.txt")); //还原对象; Object obj=ois.readObject(); //释放资源 ois.close(); System.out.println(obj); } private static void write() throws IOException { // TODOAuto-generated method stub ObjectOutput oos = new ObjectOutputStream(new FileOutputStream("oos.txt")); //创建对象 person p = new person("dephi",25); oos.writeObject(p); //释放资源; oos.close(); } 类的序列化:NotSerializableException:未序列化异常 * * 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。 * 该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口。 * * java.io.InvalidClassException: * cn.itcast_07.Person; local classincompatible: * stream classdesc serialVersionUID =-2071565876962058344, * local class serialVersionUID = -8345153069362641443 * * 为什么会有问题呢? * Person类实现了序列化接口,那么它本身也应该有一个标记值。 * 这个标记值假设是100。 * 开始的时候: * Person.class-- id=100 * wirte数据: oos.txt -- id=100 * read数据: oos.txt -- id=100 * * 现在: * Person.class-- id=200 * wirte数据: oos.txt -- id=100 * read数据: oos.txt -- id=100 * 我们在实际开发中,可能还需要使用以前写过的数据,不能重新写入。怎么办呢? * 回想一下原因是因为它们的id值不匹配。 * 每次修改java文件的内容的时候,class文件的id值都会发生改变。 * 而读取文件的时候,会和class文件中的id值进行匹配。所以,就会出问题。 * 但是呢,如果我有办法,让这个id值在java文件中是一个固定的值,这样,你修改文件的时候,这个id值还会发生改变吗? * 不会。现在的关键是我如何能够知道这个id值如何表示的呢? * 不用担心,你不用记住,也没关系,点击鼠标即可。 * 你难道没有看到黄色警告线吗? * * 我们要知道的是: * 看到类实现了序列化接口的时候,要想解决黄色警告线问题,就可以自动产生一个序列化id值。 * 而且产生这个值以后,我们对类进行任何改动,它读取以前的数据是没有问题的。 * * 注意: * 我一个类中可能有很多的成员变量,有些我不想进行序列化。请问该怎么办呢? * 使用transient关键字声明不需要序列化的成员变量 */public class Person implements Serializable { private static final long serialVersionUID = -2071565876962058344L; private String name; // private int age; private transient int age; // int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ",age=" + age + "]"; }}
Properties集合
Properties概述:
Properties属性集合类,是一个可以和IO流相结合的使用的集合类。
Properties可以保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串;
是Hashtable子类,说明是一个Map集合;
Propertiesprop = new Properties(); //添加元素; prop.put("001" , "hello"); prop.put("002", "world"); prop.put("003", "java"); //遍历集合 Set<Object> set = prop.keySet(); for(Object key : set){ Objectvalue = prop.get(key); System.out.println(key + "----"+ value); } }}
Properties的特殊功能使用:
特殊功能:
publicObject setProperty(String key,String value):添加元素
publicString getProperty(String key):获取元素
publicSet<String> stringPropertyNames():获取所有的键的集合
// 创建集合对象 Properties prop = new Properties(); // 添加元素 prop.setProperty("张三", "30"); prop.setProperty("李四", "40"); prop.setProperty("王五", "50"); // public Set<String> stringPropertyNames():获取所有的键的集合 Set<String> set =prop.stringPropertyNames(); for (String key : set) { String value = prop.getProperty(key); System.out.println(key + "---" + value); } }
Properties和IO流的结合使用:
这里的集合必须是Properties集合;
Public void load(Reader reader):把文件中的数据读取到集合中
Public void store(Writer writer, String comments) ;把集合中的数据存储到文件
private static void myStore() throws IOException { //创建集合对象 Properties prop = new Properties(); prop.setProperty("刘洋", "23"); prop.setProperty("刘明宇", "20"); prop.setProperty("江代欣", "22"); Writer w = new FileWriter("me.txt"); prop.store(w, "hellworld"); w.close(); }
private static void myload() throws IOException { // TODOAuto-generated method stub Properties prop = new Properties(); Reader r = new FileReader("oos.txt"); prop.load(r); r.close(); System.out.println("prop"+ prop); }
案例:判断文件中是否有指定的键如果有就修改值得案列:
Properties prop = new Properties(); Reader r = new FileReader("me.txt"); prop.load(r); r.close(); //遍历集合//Set<String>set = prop.stringPropertyNames(); 拿到所有的键 Set<Object> st= prop.keySet(); for(Object obj : st){ String s = (String) obj; if("刘明宇".equals(s)){ prop.setProperty(s, "2525"); break; } } //把集合中的数据重新存储到文件中 Writer w= new FileWriter("me.txt"); prop.store(w, "九月"); w.close();}
- 黑马程序员——Java基础--IO流(二)
- 黑马程序员——Java基础--------IO流(二)
- 黑马程序员——JAVA基础----IO流(二)
- 黑马程序员——Java基础---IO流(二)
- 黑马程序员——Java基础--IO(二)
- 黑马程序员——Java基础——IO(二)
- 黑马程序员——java基础-IO(二)
- 黑马程序员——Java基础---IO(二)
- 黑马程序员——java基础——IO流(二)
- 黑马程序员——Java基础——IO流(二)
- 黑马程序员——java基础—IO流(二)
- 黑马程序员——JAVA基础------IO流(二)----字节流
- 黑马程序员——java基础--IO流(篇二)
- 黑马程序员——Java基础IO流总结(二)
- 黑马程序员—java基础学习--IO ( Input Output )流(二)
- 黑马程序员——Java IO流(二)
- 黑马程序员——Java之IO流(二)
- 黑马程序员——JAVA基础-IO流(一)
- 文件对象-写操作
- hdu1012 u Calculate e
- Linux安装rz/sz命令
- Maven多环境参数管理
- Linux 性能监控
- 黑马程序员——java基础—IO流(二)
- 压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate
- c++学习笔记 类继承
- iOS Code Signing到底什么鬼
- Dubbo-Admin管理平台和Zookeeper注册中心的搭建
- JVM虚拟机堆内存大小
- 关于shell变量的第一个shell脚本
- Android应用程序组件(三)
- 关于mysql的procedure的一些细节