嘿,程序员——IO流(二)


File类

用来将文件或者文件夹封装成对象。方便对文件与文件夹进行操作。File对象可以作为参数传递给流的构造函数。

importjava.io.*;
classFileDemo
{
         public static void main(String[] args)
         {
                   consMethod();
         }
                   //创建File对象
         public static void consMethod()
         {
                   //将a.txt封装成file对象,可以将已有的和未出现的文件或者文件夹封装成对象
                   File f1=newFile("c:\\abc\\a.txt");
                   File f2=newFile("c:\\abc","b.txt");
                   File d=newFile("c:\\abc");
                   File f3=newFile(d,"c.txt");
                   sop("f1:"+f1);
                   sop("f2:"+f2);
                   sop("f3:"+f3);
                   //目录分隔符separator
                   File f4=newFile("c:"+File.separator+"abc\\zz"+File.separator+"d.txt");
         }
         public static void sop(Object obj)
         {
                   System.out.println(obj);
         }
}

File类常见方法:

1、创建

   boolean createNewFile();在指定位置创建文件,如果该文件已经存在,则不创建,返回false。

                           和输出流不一样,输出流对象一建立就创建文件,而且文件已经存在,会覆盖。

   boolean mkdir():创建文件夹

   boolean mkdirs():创建多级目录

2、删除

   boolean delete();删除失败返回false。

   void deleteOnExit();在程序退出时删除指定文件。

3、判断

   canExecute();是否能执行

   boolean exists():文件是否存在

   isDirctory():是否是一个目录

   isFile():是否是一个文件

   isHidden():是否是隐藏

   isAbsolute():是否是绝对路径

4、获取信息

   getName();

   getPath();路径

   getParent();

   getAbsoutePath();绝对路径

   lastModidied();最后一次修改时间

   length();

importjava.io.*;
classFileDemo1
{
         public static void main(String[] args)
         {
                   method_5();
         }
         public static void method_5()
         {
                   File f1=newFile("c:\\T.java");
                   File f2=newFile("c:\\H.java");
                   sop("rename:"+f1.renameTo(f2));
         }
         public static void method_4()
         {
                   File f=newFile("abc\\a.txt");
                   sop("path:"+f.getPath());
        sop("abspath:"+f.getAbsolutePath());
                   sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null
                                                //如果相对路径中有上一层目录,则该目录就是返回结果。
         }
         public static void method_3()throwsIOException
         {
                   File f=newFile("file.txt");
 
        f.createNewFile();
                   f.mkdir();
                   //记住在判断文件对象是否是文件或者目录时,必须先判断该文件对象封装的内容是否存在
                   //通过exists判断
                   sop("dir:"+f.isDirectory());
                   sop("file:"+f.isFile());
         }
    public static void method_2()throwsIOException
         {
       File f=new File("file.txt");
           //sop("exists:"+f.exists());
           //sop("execute:"+f.canExecute());
 
           //创建文件夹
           File dir=new File("abc\\aa");
           sop("dir:"+dir.mkdir());//只能创建两级
         }
         public static void method_1()throwsIOException
         {
                   File f=newFile("file.txt");
                   sop("create="+f.createNewFile());
         }
        
         public static void sop(Object obj)
         {
                   System.out.println(obj);
         }
}
 

调用list方法的File对象必须是封装了一个目录,该目录还必须存在

importjava.io.*;
classFileDemo2
{
         public static void main(String[] args)
         {
                   //listDemo();
                   File dir=newFile("c:\\");
                   File[] files=dir.listFiles();
                   for(File f:files)
                   {
                            System.out.println(f.getName()+"::"+f.length());
                   }
         }
         public static void listDemo()
         {
                   File dir=newFile("c:\\");
                   String[] arr=dir.list(newFilenameFilter()
                   {
            public boolean accept(File dir,Stringname)
                            {
                                     returnname.endsWith(".zip");
                            }
                   });
                   for(String name:arr)
                   {
                            System.out.println(name);
                   }
         }
}

列出指定目录下文件或文件夹,包括子目录中的内容。

也就是列出指定目录下所有内容。

 

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。

在列出过程中出现的还是目录的话,还可以再次调用本功能。

也就是函数自身调用自身。

这种表现形式,或者编程手法,称为递归。

递归注意:

1、限定条件

2、要注意递归的次数,尽量避免内存溢出。

importjava.io.*;
classFileDemo3
{
         public static void main(String[] args)
         {
                   File dir=newFile("d:\\java");
                   showDir(dir);
         }
         public static void showDir(File dir)
{
         File[] files=dir.listFiles();
         for(int x=0;x<files.length;x++)
         {
                   if(files[x].isDirectory())
                            showDir(files[x]);
                   else
                            System.out.println(files[x]);
         }
}
}

带层次列出:

列出指定目录下文件或文件夹,包括子目录中的内容。

也就是列出指定目录下所有内容。

 

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。

在列出过程中出现的还是目录的话,还可以再次调用本功能。

也就是函数自身调用自身。

这种表现形式,或者编程手法,称为递归。

递归注意:

1、限定条件

2、要注意递归的次数,尽量避免内存溢出。

importjava.io.*;
classFileDemo3
{
         public static void main(String[] args)
         {
                   File dir=newFile("d:\\java");
                   showDir(dir,0);
         }
         public static String getLevel(intlevel)
         {
                   StringBuilder sb=newStringBuilder();
                   sb.append("|--");
                   for(int x=0;x<level;x++)
                   {
                            sb.insert(0,"   ");
                   }
                   return sb.toString();
         }
         public static void showDir(File dir,intlevel)
    {
                   //System.out.println(getLevel(level)+dir.getName());
                   level++;
            File[] files=dir.listFiles();
            for(int x=0;x<files.length;x++)
            {
                       if(files[x].isDirectory())
                                showDir(files[x],level);
                       else
                               System.out.println(getLevel(level)+files[x]);
             }
     }
}

练习:

将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。

建立一个java文件列表文件。

 

思路:

1、对指定的目录进行递归。

2、获取递归过程中所有的java文件的路径

3、将这些路径存储到集合中。

4、将集合中的数据写入到一个文件中。

importjava.io.*;
importjava.util.*;
class  JavaFileList
{
         public static void main(String[] args)throws IOException
         {
                   File dir=newFile("d:\\java");
                   List<File> list=newArrayList<File>();
                   fileToList(dir,list);
                   //System.out.println(list.size());
                   File file=newFile(dir,"javalist.txt");
                   writeToFile(list,file.toString());
         }
         public static void fileToList(Filedir,List<File> list)
         {
                   File[] files=dir.listFiles();
                   for(File file:files)
                   {
                            if(file.isDirectory())
                                     fileToList(file,list);
                            else
                            {
                                     if(file.getName().endsWith(".java"))
                                               list.add(file);
                            }
                   }
         }
         public static voidwriteToFile(List<File> list,String javaListFile)throws IOException
         {
                   BufferedWriter bufw=null;
                   try
                   {
                            bufw=newBufferedWriter(new FileWriter(javaListFile));
                            for(File f:list)
                            {
                                     Stringpath=f.getAbsolutePath();
                                     bufw.write(path);
                                     bufw.newLine();
                                     bufw.flush();
                            }
                   }
                   catch (IOException e)
                   {
                            throw e;
                   }
                   finally
                   {
                            try
                            {
                                     if(bufw!=null)
                                               bufw.close();
                            }
                            catch (IOExceptione)
                            {
                                     throw e;
                            }
                   }
         }
}

Propertiers是hashtable的子类

也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。

是集合中和IO技术相结合的集合容器。

该对象的特点:可以用于键值对形式的配置文件.

那么在加载数据时,需要数据有固定格式:键=值。

importjava.io.*;
importjava.util.*;
class  PropertiesDemo
{
         public static void main(String[] args)throws IOException
         {
                   loadDemo();
         }
         public static void loadDemo()throwsIOException
         {
                   Properties prop=new Properties();
                   FileInputStream fis=newFileInputStream("info.txt");
                   //将流中的数据加载进集合。
                   prop.load(fis);
                   prop.setProperty("wangwu","99");
                   FileOutputStream fos=newFileOutputStream("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()throwsIOException
         {
                   BufferedReader bufr=newBufferedReader(new FileReader("info.txt"));
                   String line=null;
                   Properties prop=newProperties();
                   while((line=bufr.readLine())!=null)
                   {
                            String[]arr=line.split("=");
                            //System.out.println(arr[0]+"....."+arr[1]);
                            prop.setProperty(arr[0],arr[1]);
                   }
                   bufr.close();
         }
         //设置和获取元素。
         public static void setAndGet()
         {
                   Properties prop=newProperties();
                   prop.setProperty("zhangsan","30");
                   prop.setProperty("lisi","39");
                   Stringvalue=prop.getProperty("lisi");
                   System.out.println(value);
                   Set<String>names=prop.stringPropertyNames();
                   for(String s:names)
                   {
                            System.out.println(s+":"+prop.getProperty(s));
                   }
         }
}

打印流:

该流提供了打印方法,可以将各种数据类型的数据都原样打印。

 

字节打印流:

PrintStream

构造函数可以接收的参数类型:

1、file对象。File

2、字符串路径。String

3、字节输出流。OutputStream

字符打印流:

PrintWriter

构造函数可以接收的参数类型:

1、file对象。File

2、字符串路径。String

3、字节输出流。OutputStream

4、字符输出流。Writer

importjava.io.*;
class  PrintStreamDemo
{
         public static void main(String[] args)throws IOException
         {
                   BufferedReader bufr=newBufferedReader(new InputStreamReader(System.in));
                   //PrintWriter out=newPrintWriter(System.out,true);
                   PrintWriter out=newPrintWriter(new FileWriter("a.txt"),true);
                   String line=null;
                   while((line=bufr.readLine())!=null)
                   {
                            if("over".equals(line))
                                     break;
                            out.println(line.toUpperCase());
                   }
                   out.close();
                   bufr.close();
         }
} 

合并流:

importjava.io.*;
importjava.util.*;
class  SequenceDemo
{
         public static void main(String[]args)throws IOException
         {
                   Vector<FileInputStream>v=new Vector<FileInputStream>();
                   v.add(newFileInputStream("d:\\1.txt"));
                   v.add(newFileInputStream("d:\\2.txt"));
                   v.add(newFileInputStream("d:\\3.txt"));
                   Enumeration<FileInputStream>en=v.elements();
                   SequenceInputStream sis=newSequenceInputStream(en);
                   FileOutputStream fos=newFileOutputStream("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();
         }
}

切割流然后合并:

importjava.io.*;
importjava.util.*;
classSplitFile
{
         public static void main(String[] args)throws IOException
         {
                   merge();
         }
         public static void merge()throwsIOException
         {
                   ArrayList<FileInputStream>al=new ArrayList<FileInputStream>();
                   for(int x=1;x<3;x++)
                   {
            al.add(newFileInputStream("d:\\java\\SplitFile\\"+x+".part"));
                   }
                   finalIterator<FileInputStream> it=al.iterator();
                   Enumeration<FileInputStream>en=new Enumeration<FileInputStream>()
                   {
                            public booleanhasMoreElements()
                            {
                                     returnit.hasNext();
                            }
                            publicFileInputStream nextElement()
                            {
                                     returnit.next();
                            }
                   };
                   SequenceInputStream sis=newSequenceInputStream(en);
                   FileOutputStream fos=newFileOutputStream("d:\\java\\SplitFile\\0.jpg");
                   byte[] buf=new byte[1024];
                   int len=0;
                   while((len=sis.read(buf))!=-1)
                   {
                            fos.write(buf,0,len);
                   }
                   fos.close();
                   sis.close();
         }
         public static void splitFile()throwsIOException
         {
                   FileInputStream fis=newFileInputStream("d:\\1.jpg");
                   FileOutputStream fos=null;
                   byte[] buf=newbyte[1024*1024];
                   int len=0;
                   int count=1;
                   while((len=fis.read(buf))!=-1)
                   {
                            fos=newFileOutputStream("d:\\java\\SplitFile\\"+(count++)+".part");
                            fos.write(buf,0,len);
                            fos.close();
                   }
                   fis.close();
         }
}

管道流

importjava.io.*;
classPipedStream
{
         public static void main(String[] args)throws IOException
         {
                   PipedInputStream in=newPipedInputStream();
                   PipedOutputStream out=newPipedOutputStream();
                   in.connect(out);
                   Read r=new Read(in);
                   Write w=new Write(out);
                   new Thread(r).start();
                   new Thread(w).start();
         }
}
 
class Readimplements Runnable
{
         private PipedInputStream in;
         Read(PipedInputStream in)
         {
                   this.in=in;
         }
         public void run()
         {
                   try
                   {
                            byte[] buf=newbyte[1024];
                            System.out.println("读取前。。没有数据,阻塞。。");
                            intlen=in.read(buf);
                            System.out.println("读到数据。。阻塞结束");
                            String s=newString(buf,0,len);
                            System.out.println(s);
                            in.close();
                   }
                   catch (IOException e)
                   {
                            throw newRuntimeException("管道读取流失败");
                   }
         }
}
class Writeimplements Runnable
{
         private PipedOutputStream out;
         Write(PipedOutputStream out)
         {
                   this.out=out;
         }
         public void run()
         {
                   try
                   {
                            System.out.println("开始写入数据,等待6秒后。。。");
                            Thread.sleep(6000);
                            out.write("nimei de keng die".getBytes());
                            out.close();
                   }
                   catch (Exception e)
                   {
                            throw newRuntimeException("管道输出流失败");
                   }
         }
}

RandomAccessFile

该类不算是IO体系中子类。

而是直接继承自Object。

但是它是IO包中的成员,因为它具备读和写功能。

内部封装了一个数组,而且通过指针对数组的元素进行操作。

可以通过getFilePointer获取指针位置,

同时可以通过seek改变指针的位置。

其实完成读写的原理就是内部封装了字节输入流和输出流。

通过构造函数可以看出,该类只能操作文件。

而且操作文件还有模式:只读r,读写rw等。

 

如果模式为只读r,则不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常。

如果模式是读写rw,操作的文件不存在,会自动创建,如果存在则不会覆盖。

importjava.io.*;
class  RandomAccessFileDemo
{
         public static void main(String[] args)throws IOException
         {
                   //writeFile();
                   readFile();
         }
         public static void readFile()throws IOException
         {
                   RandomAccessFile raf=newRandomAccessFile("ran.txt","r");
                   //调整对象中指针。
                   //raf.seek(8);
                   //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 writeFile2()throwsIOException
         {
        RandomAccessFile raf=newRandomAccessFile("ran.txt","rw");
                   raf.seek(8*3);//设置位置
        raf.write("周七".getBytes());
                   raf.writeInt(103);
                   raf.close();
         }
         public static void writeFile()throwsIOException
         {
                   RandomAccessFile raf=newRandomAccessFile("ran.txt","rw");
                   raf.write("李四".getBytes());
                   raf.writeInt(97);
                   raf.write("王五".getBytes());
                   raf.writeInt(99);
                   raf.close();
         }
}


打印流:PrintWriter与PrintStream可以直接操作输入流和文件

序列流:SequenceInputStream对多个流进行合并

操作对象:ObjectInputStream与ObjectOutputStream被操作的对象需要实现Serializable

序列化接口:Serializable

管道流:PipedInputStream和PipedOutputStream,输入输出可以直接进行连接,通过结合线程使用。

RandomAccessFile

随机访问文件,自身具备读写的方法。

通过skipBytes(intx),seek(int x)来达到随机访问。

 

IO包中的其他流:

操作基本数据类型:DataInputStream和DataOutputStream

DataInputStream与DataOutputStream

可以用于操作基本数据类型的数据流对象

importjava.io.*;
class  DataStreamDemo
{
         public static void main(String[] args)throws IOException
         {
                   //writeData();
                   //readData();
                   //writeUTFDemo();
 
                   //OutputStreamWriter osw=newOutputStreamWriter(newFileOutputStream("utf.txt","utf-8"));
                   //dos.write("你好");//此文件6个字节
                   //dos.close();
        readUTFDemo();
         }
         public static void readUTFDemo()throwsIOException
         {
                   DataInputStream dis=newDataInputStream(new FileInputStream("utfdata.txt"));
                   String s=dis.readUTF();
                   System.out.println(s);
                   dis.close();
 
         }
    public static void writeUTFDemo()throwsIOException
         {
                   DataOutputStream dos=new DataOutputStream(newFileOutputStream("utfdata.txt"));
                   dos.writeUTF("你好");//此文件8个字节,只能用DataInputStream读
                   dos.close();
         }
    public static void readData()throwsIOException
         {
        DataInputStream dis=newDataInputStream(new FileInputStream("data.txt"));
                   int num=dis.readInt();
                   boolean b=dis.readBoolean();
                   double d=dis.readDouble();
                   System.out.println("num="+num);
                   System.out.println("b="+b);
                   System.out.println("d="+d);
         }
         public static void writeData()throwsIOException
         {
                   DataOutputStream dos=newDataOutputStream(new FileOutputStream("data.txt"));
                   dos.writeInt(234);
                   dos.writeBoolean(true);
                   dos.writeDouble(9887.543);
                   dos.close();
         }
}

编码表:

计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字表示,并一一对应,形成一张表,这就是编码表。

ASCII:美国标准信息交换码。用一个字节的7位可以表示。

ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位表示。

GB2312:中国的中文编码表。

GBK:中国的中文编码表升级,融合了更多的中文文字符号。

Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示。java语言使用的就是unicode。

UTF-8:最多用三个字节来表示一个字符。

importjava.io.*;
classEncodeStream
{
         public static void main(String[] args)throws IOException
         {
                   //writeText();
                   readText();
         }
         public static void readText()throwsIOException
         {
                   //InputStreamReader isr=newInputStreamReader(new FileInputStream("utf.txt"),"GBK");
                   InputStreamReader isr=newInputStreamReader(new FileInputStream("gbk.txt"),"UTF-8");
                   char[] buf=new char[10];
                   int len=isr.read(buf);
                   String str=new String(buf,0,len);
                   System.out.println(str);
                   isr.close();
         }
         public static void writeText()throwsIOException
         {
                   OutputStreamWriter osw =newOutputStreamWriter(newFileOutputStream("utf.txt"),"UTF-8");
                   //OutputStreamWriter osw =newOutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
                   osw.write("你好");
                   osw.close();
         }
}

编码:字符串变成字节数组

解码:字节数组变成字符串

 

String-->byte[];str.getBytes(charsetName);

byte[]-->String:newString(byte[],charsetName);

class  EncodeDemo
{
         public static void main(String[] args)throws Exception
         {
                   String s="你好";
                   byte[]b1=s.getBytes("GBK");
                   String s1=newString(b1,"ISO8859-1");
                   //对s1进行ISO8859-8编码
                   byte[]b2=s1.getBytes("ISO8859-1");
                   String s2=newString(b2,"GBK");
                   System.out.println("s1="+s2);
                   //System.out.println(Array.toString(b1));
         }
}

有五个学生,每个学生有3门课的成绩。

从键盘输入以上数据(包括姓名,三门课成绩),

输入格式:如:zhangsan,30,40,60计算出总成绩,

并把学生的信息和计算出的总分数高低顺序存放在磁盘文件"stud.txt"中。

 

1、描述学生对象。

2、定义一个可操作学生对象的工具类。

思想:

1、通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。

2、因为学生有很多,那么就需要存储,使用到集合,因为要对学生的总分排序,

   所以可以使用TreeSet。

3、将集合的信息写入到一个文件中。

importjava.io.*;
importjava.util.*;
class  StudentInfoTest
{
         public static void main(String[] args)throws IOException
         {
                   Comparator<Student>cmp=Collections.reverseOrder();
                   Set<Student>stus=StudentInfoTool.getStudents(cmp);
                   StudentInfoTool.writeToFile(stus);
         }
}
classStudent implements Comparable<Student>
{
         private String name;
         private int ma,cn,en;
         private int sum;
         Student(String name,int ma,int cn,inten)
         {
                   this.name=name;
                   this.ma=ma;
                   this.cn=cn;
                   this.en=en;
                   sum=ma+cn+en;
         }
         public int compareTo(Student s)
         {
                   int num=newInteger(this.sum).compareTo(new Integer(s.sum));
                   if(num==0)
                            returnthis.name.compareTo(s.name);
                   return num;
         }
         public String getName()
         {
                   return name;
         }
         public int getSum()
         {
                   return sum;
         }
         public int hashCode()
         {
                   returnname.hashCode()+sum*78;
         }
         public boolean equals(Object obj)
         {
                   if(!(obj instanceof Student))
                            throw newClassCastException("类型不配");
                   Student s=(Student)obj;
                   returnthis.name.equals(s.name)&&this.sum==s.sum;
         }
         public String toString()
         {
                   return"Student["+name+","+ma+","+cn+","+en+"]";
         }
}
classStudentInfoTool
{
         public static Set<Student>getStudents()throws IOException
         {
                   return getStudents(null);
         }
         public static Set<Student>getStudents(Comparator<Student> cmp)throws IOException
         {
                   BufferedReader bufr=newBufferedReader(new InputStreamReader(System.in));
                   String line=null;
                   Set<Student> stus=null;
                   if(cmp==null)
                            stus=newTreeSet<Student>();
                   else
                            stus=newTreeSet<Student>(cmp);
                   while((line=bufr.readLine())!=null)
                   {
                            if("over".equals(line))
                                     break;
                            String[]info=line.split(",");
                            Student stu=newStudent(info[0],Integer.parseInt(info[1]),
                                                                Integer.parseInt(info[2]),
                                                                Integer.parseInt(info[3]));
                            stus.add(stu);
                   }
                   bufr.close();
                   return stus;
         }
         public static voidwriteToFile(Set<Student> stus)throws IOException
         {
        BufferedWriter bufw=newBufferedWriter(new FileWriter("stud.txt"));
                   for(Student stu:stus)
                   {
                       bufw.write(stu.toString()+"\t");
                            bufw.write(stu.getSum()+"");
                            bufw.newLine();
                            bufw.flush();
                   }
                   bufw.close();
         }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值