1,File 类。用于将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。File 对象可以作为参数传递给流的构造函数。File类常见方法:1)创建。boolean createNewFile();在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立就创建文件,而且文件已经存在,会覆盖。boolean mkdir();创建一级文件夹。boolean mkdirs();创建多级文件夹。2)删除。boolean delete();删除失败返回假。void deleteOnExit();在程序退出时删除指定文件。3)判断。boolean exists();文件是否存在。canExecute();//是否可执行。isFile();isDirectory();isHidden();//是否隐藏isAbsolute();//判断是否是绝对路径。文件不存在,也能判断。4)获取信息。getName();getPath();getParent();getAbsolutePath();long lastModified();long length();File dir=new File("d:\\javaDemo\\day06");//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。//采用匿名内部类作为文件名过滤器,复写accept方法。String[] arr=dir.list( new FilenameFilter(){public boolean accept(File dir,String name){return name.endsWith(".txt");}});for(String name:arr) {System.out.println(name);}2,列出指定目录下文件或者文件夹,包含子目录中的内容,也就是列出指定目录下所有内容。因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。在列出过程中出现的还是目录的话,可以再次调用本功能,也就是函数自身调用自身。这种表现形式或者编程手法称为 递归。递归要注意:1)限定条件。2)要注意递归次数,尽量避免内存溢出。//返回每一级的文件和目录名。public static String getLevel(int level){StringBuilder sb=new StringBuilder();for(int x=0;x<level;x++){sb.append(" ");}sb.append("|--");return sb.toString();}public static void showDir(File dir,int level){System.out.println(getLevel(level)+dir.getName());level++;File[] files=dir.listFiles();for(int x=0;x<files.length;x++){//如果遍历到目录则递归调用show。if(files[x].isDirectory()){showDir(files[x],level);}elseSystem.out.println(getLevel(level)+files[x].getName());}}3,Properties 是hashtable的子类。它具备了Map集合的特点,而且它里面存储的键值对都是字符串,是集合中和IO技术相结合的集合容器。该对象的特点:可以用于键值对形式的配置文件。那么在加载数据时,需要数据有固定格式:键=值。public static void loadDemo()throws IOException{Properties prop=new Properties();FileInputStream fis=new FileInputStream("info.txt");//将流中的数据加载进集合。 加载字符流是在JDK1.6版本出现的。prop.load(fis);prop.setProperty("wangwu","88");FileOutputStream fos=new FileOutputStream("info.txt");prop.store(fos,"haha"); //haha为注释信息。fos.close();fis.close();}
4,IO 包中的其他类。1) 打印流。PrintWriter与PrintStream ,可以直接操作输入流和文件。该流提供了打印方法,可以将各种数据类型的数据都原样打印。字节打印流:构造函数可以接收的参数类型:1)file对象。File2)字符串路径。String3)字节输出流。OutputStream字符打印流:构造函数可以接收的参数类型:1)file对象。File2)字符串路径。String3)字节输出流。OutputStream4)字符输出流。WriterBufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter("a.txt")),true);2) 序列流。SequenceInputStream,对多个流进行合并。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();3)对象流。ObjectInputStream 与ObjectOutputStream ,被操作的对象需要实现Serializable( 标记接口)。class Person implements Serializable{public static final long serialVersionUID=42L;......}public static void readObj()throws Exception{ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));Person p=(Person)ois.readObject();ois.close();}public static void writeObj()throws IOException{ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));oos.writeObject(new Person("lisi",35,"kr"));oos.close();}4)RandomAccessFile ,随机访问文件,自身具备读写方法。RandomAccessFile 该类不算是IO体系中的子类, 而是直接继承自Object, 但是它是IO包中成员,因为它具备读和写功能。 内部封装了一个数组,而且通过指针对数组中的元素进行操作。 可以通过getFilePointer获取指针位置, 可以通过seek改变指针的位置。 其实完成读写的原理,就是内部封装了字节输入流和输出流。 通过构造函数可以看出,该类只能操作文件, 而且操作文件还有模式:只读r,读写rw等。 如果模式为只读r,不会创建文件,回去读取一个已存在的文件,如果该文件不存在,则会出现异常。 如果模式为rw,操作的文件不存在,会自动创建,如果存在,则不会覆盖。通过 skipBytes(int x),seek(int x) 来达到随机访问。public static void readFile()throws IOException {RandomAccessFile raf=new RandomAccessFile("ran.txt","r");//raf.write("haha".getBytes()); //拒绝访问。//调整对象中的指针。前后都能指。//raf.seek(8*1);//跳过指定的字节数。只能往后跳。raf.skipBytes(20);byte[] buf=new byte[4];raf.read(buf);String name=new String(buf);int age=raf.readInt();System.out.println("name="+name);raf.close();}public static void writeFile()throws IOException {RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");raf.seek(8*3);raf.write("周七".getBytes());raf.writeInt(103);raf.close();}5)管道流 。 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];int len=in.read(buf);String s=new String(buf,0,len);in.close();}catch (IOException e) {throw n ew RuntimeException("管道读取流失败");}}}class Write implements Runnable {private PipedOutputStream out;Write(PipedOutputStream out) {this.out=out;}public void run() {try {Thread.sleep(6000);out.write("piped come on".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); // 使此传送 reader 连接到传送 writer 。out.connect(in); // 使此传送 writer连接到接收方。Read r=new Read(in);Write w=new Write(out);Thread t1=new Thread(r);Thread t2=new Thread(w);t1.start();t2.start();}}6) 操作基本数据类型 DataInputStream 与 DataOutputStream操作字节数组 ByteArrayInputstream 与 ByteArrayOutputStream操作字符数组 CharArrayReader 与 CharArrayWriter操作字符串 StringReader 与 StringWriter
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));dos.writeInt(234);dos.writeBoolean(true);dos.writeDouble(9887.5433);dos.close();
5 ,字符编码。字符流的出现为了方便操作字符。更重要的是加入了编码转换,通过子类转换流来完成。InputStreamReader ,OutputStreamWriter 。在两个对象进行构造的时候可以加入字符集。编码表的由来: 计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表。ASCII :美国标准信息交换码。用一个字节的7 位可以表示。ISO8859-1 :拉丁码表。欧洲码表。用一个字节的8 位表示。GB2312 :中国的中文编码表。GBK :中国的中文编码表升级,融合了更多的中文文字符号。Unicode: 国标标准码,融合了多种文字。所有文字都用两个字节来表示,java 语言使用的就是unicode 。UTF-8 :最多用三个字节来表示一个字符。转换流的编码应用: 可以将字符以指定编码格式存储,可以对文本数据指定编码格式来解读,指定编码表的动作由构造函数完成 。
编码解码过程:String s="你好";
byte[] b1=s.getBytes("GBK");//使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。String s1=new String(b1,"ISO8859-1");//通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
byte[] b2=s1.getBytes("ISO8859-1");//对s1进行iso8859-1编码。String s2=new String(b2,"GBK");//使用GBK解码。
编解码逆过程,通过画图理解:
编码中的特例:最特殊-----“联通”解决:联通不要在文本中打头,否则GBK的“联通”会被识别为用UTF-8来解码。utf-8编码规则:单字节:0...双字节:110... 10...三字节:1110... 10... 10...String s="联通"; //[-63,-86,-51,-88] 1100001 10101010 11001101 10101000byte[] by=s.getBytes("gbk");for(byte b:by){System.out.println(Integer.toBinaryString(b&255));}
黑马程序员——14JavaIO输入输出2
最新推荐文章于 2015-10-19 16:20:25 发布