黑马程序员-10 IO流2 File,properties,合并流,对象持久化,管道流,RandomAccessFile
File 将文件和文件夹封装成对象
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。
boolean exists() :文件是否存在.
isFile():
isDirectory();
isHidden();
isAbsolute();
4,获取信息。
getName():
getPath():
getParent():
getAbsolutePath()
long lastModified()
long length()
==============================================================
import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.util.Date; public class FileMethodDemo { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // getDemo(); // createAndDeleteDemo(); // isDemo(); // renameToDemo(); // listRootsDemo(); } public static void listRootsDemo() { File[] files = File.listRoots(); for (File file : files) { System.out.println(file); } File file = new File("c:\\"); System.out.println(file.getFreeSpace()); System.out.println(file.getTotalSpace()); System.out.println(file.getUsableSpace()); } public static void renameToDemo() { File f1 = new File("c:\\0.mp3"); File f2 = new File("d:\\9.mp3"); f1.renameTo(f2); } public static void isDemo() throws IOException { File f = new File("a.txt"); boolean b = f.exists(); System.out.println("exists?:" + b); // 最好先判断是否存在 System.out.println("isFile?:" + f.isFile()); System.out.println("isDirectory?:" + f.isDirectory()); } public static void createAndDeleteDemo() throws IOException { File dir = new File("abc\\a\\b\\c\\d"); // boolean b=dir.mkdir();//创建单级目录 // boolean b=dir.mkdirs();//创建多级目录 // System.out.println("b:"+b); System.out.println("del:" + dir.delete()); // 文件的创建和删除 File file = new File("file.txt"); /* * 和输出流不一样,如果文件不存在,则创建;如果文件存在,则不创建。 */ // boolean b=file.createNewFile(); // System.out.println("b:"+b); // boolean b=file.delete(); // System.out.println("b:"+b); } public static void getDemo() { File file = new File("a.txt"); String name = file.getName(); String abspath = file.getAbsolutePath(); String path = file.getPath(); long len = file.length(); long time = file.lastModified(); Date date = new Date(time); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); String str_time = dateFormat.format(date); System.out.println("parent:" + file.getParent());// 文件对象中是绝对路径时,获取父目录;相对路径时,null System.out.println("name:" + name); System.out.println("path:" + path); System.out.println("abspath:" + abspath); System.out.println("len:" + len); System.out.println("time:" + time); System.out.println("str_time:" + str_time); } }
===============================================
Properties是hashtable的子类。
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。
import java.io.*; import java.util.*; class PropertiesDemo { public static void main(String[] args) throws IOException { //method_1(); loadDemo(); } public static void loadDemo()throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream("info.txt"); //源文件 //将流中的数据加载进集合。 prop.load(fis); //从输入流中读取属性列表(键和元素对)。 prop.setProperty("wangwu","39"); FileOutputStream fos = new FileOutputStream("info.txt"); prop.store(fos,"haha"); // System.out.println(prop); prop.list(System.out); fos.close(); fis.close(); } //演示,如何将流中的数据存储到集合中。 //想要将info.txt中键值数据存到集合中进行操作。 /* 1,用一个流和info.txt文件关联。 2,读取一行数据,将该行数据用"="进行切割。 3,等号左边作为键,右边作为值。存入到Properties集合中即可。 */ public static void method_1()throws IOException { BufferedReader bufr = new BufferedReader(new FileReader("info.txt")); String line = null; Properties prop = new Properties(); while((line=bufr.readLine())!=null) { String[] arr = line.split("="); ///System.out.println(arr[0]+"...."+arr[1]); prop.setProperty(arr[0],arr[1]); } bufr.close(); System.out.println(prop); } // 设置和获取元素。 public static void setAndGet() { Properties prop = new Properties(); prop.setProperty("zhangsan","30"); prop.setProperty("lisi","39"); // System.out.println(prop); String value = prop.getProperty("lisi"); //System.out.println(value); prop.setProperty("lisi",89+""); Set<String> names = prop.stringPropertyNames(); for(String s : names) { System.out.println(s+":"+prop.getProperty(s)); } } }
==========================================================
合并流
SequenceInputStream
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
import java.io.*; import java.util.*; class SequenceDemo { public static void main(String[] args) throws IOException { Vector<FileInputStream> v = new Vector<FileInputStream>(); v.add(new FileInputStream("c:\\1.txt")); v.add(new FileInputStream("c:\\2.txt")); v.add(new FileInputStream("c:\\3.txt")); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("c:\\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(); } } =================================================================== 对象的持久化(序列化)ObjectOutputStream import java.io.*; class ObjectStreamDemo { public static void main(String[] args) throws Exception { //writeObj(); readObj(); } public static void readObj()throws Exception { 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(new FileOutputStream("obj.txt")); oos.writeObject(new Person("lisi0",399,"kr")); oos.close(); } } 被传送的类必须是被序列化的,序列号由成员变量生成,类修改之后序列号改变。 import java.io.*; class Person implements Serializable //启用Serializable实现其序列化 { public static final long serialVersionUID = 42L; //自己指定uid,也可以省略有系统生成 private String name; transient int age; //如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。也就是不能被序列化。 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; } }
================================
管道流
PipedInputStream PipedOutputStream
传送输入流应该连接到传送输出流;传送输入流会提供要写入传送输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能会死锁该线程。传送输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。
import java.io.*; class Read implements Runnable { private PipedInputStream in; Read(PipedInputStream in) { this.in = in; } public void run() { try { byte[] buf = new byte[1024]; System.out.println("读取前。。没有数据阻塞"); int len = in.read(buf); //阻塞式方法 System.out.println("读到数据。。阻塞结束"); 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 { System.out.println("开始写入数据,等待6秒后。"); Thread.sleep(6000); out.write("piped lai la".getBytes()); out.close(); } catch (Exception e) { throw new RuntimeException("管道输出流失败"); } } } class PipedStreamDemo { 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(); } }
==================================================================
RandomAccessFile
此类的实例支持对随机存取文件的读取和写入。随机存取文件的行为类似存储在文件系统中的一个大型字节数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机存取文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。
该类不是算是IO体系中子类。
而是直接继承自Object。
但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
import java.io.*; class RandomAccessFileDemo { public static void main(String[] args) throws IOException { //writeFile_2(); //readFile(); //System.out.println(Integer.toBinaryString(258)); } public static void readFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","r"); //调整对象中指针。 //raf.seek(8*1); //跳过指定的字节数 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); int age = raf.readInt(); System.out.println("name="+name); System.out.println("age="+age); raf.close(); } public static void writeFile_2()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.seek(8*0); raf.write("周期".getBytes()); raf.writeInt(103); raf.close(); } public static void writeFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.write("李四".getBytes()); raf.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); } }
======================