IO(续二)

来源:互联网 发布:vscode 安装插件 编辑:程序博客网 时间:2024/05/05 15:46

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():该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。

                       如果相对路径中有上一层目录那么该目录就是返回结果。

 

       getAbsolutePath()

       long lastModified()

       long length()

 

注意:判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在。

通过exists判断。

 

File[] files = File.listRoots();列出所有的有效盘符

 

 

File dir = new File("d:\\heima\\daily");

String[] arr = dir.list()

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

 

 

练习列出指定目录下所有内容。

 

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

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

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

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

 

递归要注意:

1,限定条件。

 

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

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++)

              {

                     if(files[x].isDirectory())

                            showDir(files[x],level);

                     else

                            System.out.println(getLevel(level)+files[x]);

              }

       }

练习

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

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

 

class  JavaFileList

{

       public static void main(String[] args) throws IOException

       {

             

              File dir = new File("d:\\java1223");

 

              List<File> list = new ArrayList<File>();

 

              fileToList(dir,list);

 

              //System.out.println(list.size());

 

 

              File file = new File(dir,"javalist.txt");

              writeToFile(list,file.toString());

 

             

 

 

       }

       public static void fileToList(File dir,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 void writeToFile(List<File> list,String javaListFile)throws IOException

       {

              BufferedWriter bufw =  null;

              try

              {

                     bufw = new BufferedWriter(new FileWriter(javaListFile));

                    

                     for(File f : list)

                     {

                            String path = f.getAbsolutePath();

                            bufw.write(path);

                            bufw.newLine();

                            bufw.flush();

                     }

 

              }

              catch (IOException e)

              {

                     throw e;

              }

              finally

              {

                     try

                     {

                            if(bufw!=null)

                                   bufw.close();

                     }

                     catch (IOException e)

                     {

                            throw e;

                     }

              }

       }

}

 

打印流:

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

 

字节打印流:

PrintStream

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

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

 

字符打印流:

PrintWriter

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

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

4,字符输出流,Writer。

 

class  PrintStreamDemo

{

       public static void main(String[] args) throws IOException

       {   //从键盘读取数据

              BufferedReader bufr =

                     new BufferedReader(new InputStreamReader(System.in));

//将a.txt中的数据打印

              PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

//PrintWriter out = new PrintWriter("a.txt");如果是这样则不能自动刷新

              String line = null;

 

              while((line=bufr.readLine())!=null)

              {

                     if("over".equals(line))

                            break;

                     out.println(line.toUpperCase());//有ln标记会自动刷新

              }

 

              out.close();

              bufr.close();

 

       }    

}

 

练习:删除一个带内容的目录。

删除原理:

在window中,删除目录从里面往外删除的。

 

既然是从里往外删除。就需要用到递归。

class  RemoveDir

{

       public static void main(String[] args)

       {

             

              File dir = new File("d:\\testdir");

              removeDir(dir);

       }

 

       public static void removeDir(File dir)

       {

              File[] files = dir.listFiles();

             

              for(int x=0; x<files.length; x++)

              {

                     if(files[x].isDirectory())

                            removeDir(files[x]);

                     else

                            System.out.println(files[x].toString()+":-file-:"+files[x].delete());

              }

 

              System.out.println(dir+"::dir::"+dir.delete());

       }

 

}

 合并流:可以将多相文件合并成一个文件

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();

 

       }

切割文件

class SplitFile

{

       public static void main(String[] args) throws IOException

       {

       splitFile();

       }

 

public static void splitFile()throws IOException

       {

              FileInputStream fis =  new FileInputStream("c:\\1.bmp");

 

              FileOutputStream fos = null;

 

 

              byte[] buf = new byte[1024*1024];

 

              int len = 0;

              int count = 1;

              while((len=fis.read(buf))!=-1)

              {

                     fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");

                     fos.write(buf,0,len);

                     fos.close();

              }

             

              fis.close();

             

       }

}

 

用于操作字节数组的流对象

 

ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。

 

ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。

 

因为这两个流对象都操作的数组,并没有使用系统资源。

所以,不用进行close关闭。

 

 

在流操作规律中有:

 

源设备,

       键盘 System.in,硬盘 FileStream,内存 ArrayStream。

目的设备:

       控制台 System.out,硬盘FileStream,内存 ArrayStream。

 

 

用流的读写思想来操作数据。

 

 

import java.io.*;

class ByteArrayStream

{

       public static void main(String[] args)

       {

              //数据源。

              ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());

 

              //数据目的

              ByteArrayOutputStream bos = new ByteArrayOutputStream();

 

              int by = 0;

 

              while((by=bis.read())!=-1)

              {

                     bos.write(by);//内部已封装了数组所以不用再定义数组了

              }

 

              System.out.println(bos.size());

              System.out.println(bos.toString());

 

       //     bos.writeTo(new FileOutputStream("a.txt"));一次性写到文件中

 

       }

}

 

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

DataInputStream与DataOutputStream

 

class DataStreamDemo

{

       public static void main(String[] args) throws IOException

       {

              //writeData();

              //readData();

 

              //writeUTFDemo();

 

//            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

//

//            osw.write("你好");

//            osw.close();

 

//            readUTFDemo();

 

       }

       public static void readUTFDemo()throws IOException

       {

              DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));

 

              String s = dis.readUTF();

 

              System.out.println(s);

              dis.close();

       }

 

 

 

       public static void writeUTFDemo()throws IOException

       {

              DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));

 

//使用的是修订版的UTF所以只能用dis.readUTF();才能正确读出

dos.writeUTF("你好");

              dos.close();

       }

 

       public static void readData()throws IOException

       {

              DataInputStream dis = new DataInputStream(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);

 

              dis.close();

       }

       public static void writeData()throws IOException

       {

              DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

 

              dos.writeInt(234);

              dos.writeBoolean(true);

              dos.writeDouble(9887.543);

 

              dos.close();

 

              ObjectOutputStream oos = null;

              oos.writeObject(new O());

 

             

       }

}

ObjectOutputStream     ObjectInputStream对象流

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();

       }

}

 

RandomAccessFile

 

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

而是直接继承自Object。

 

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

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

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

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

 

 

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

 

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

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

 

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

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

可以实现多线程下载

 

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");

//write方法只写了低四位

              raf.write("李四".getBytes());

              raf.writeInt(97);

              raf.write("王五".getBytes());

              raf.writeInt(99);

 

              raf.close();

       }

}

可以实现线程间通讯的管道流

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();

 

 

       }

}