黑马程序员——14JavaIO输入输出2


------------ android培训 java培训 、期待与您交流!------------
 
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);
}
else
System.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对象。File
                                                                 2)字符串路径。String
                                                                 3)字节输出流。OutputStream
              字符打印流:
                构造函数可以接收的参数类型:1)file对象。File
                                                                 2)字符串路径。String
                                                                 3)字节输出流。OutputStream
                                                                 4)字符输出流。Writer
                BufferedReader 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 10101000
        byte[] by=s.getBytes("gbk");
for(byte b:by){
         System.out.println(Integer.toBinaryString(b&255));

}
 

------------ android培训 java培训 、期待与您交流!------------

详情请查 看: http://edu.csdn.net/heima
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值