201711671118《Java程序设计》第十章总结

第10章 输入、输出流

从外部的储存媒介或其他程序中读入所需要的数据,需要输入流,输入流的指向为它的源。

将处理的结果写入永久的储存媒介中或传送给其他的应用程序,需要输出流。输出流的指向称为它的目的地。

java.io包(I/O流库)提供大量的流类,所有输入流都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流的子类),所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。

10.1 File类

需要获取磁盘上的文件的有关信息或在磁盘上创建新的文件等,这就需要File类。

File类的对象主要用来获取文件本身的一些信息,例如文件的所在的目录、文件的长度或文件的读写权限等,不涉及对文件的读写操作。

创建一个File对象的构造方法有3个:

File(String filename)

File(String directoryPath,String filename)

File(File dir,String filename)

filename是文件名,directoryPath是文件路径,dir为一个目录。使用File(String filename)创建文件时,该文件被认为与当前应用程序在同一目录。

10.1.1 File的方法:

    • public String getName() 获取文件的名字。
    • public boolean canRead() 判断文件是否是可读的。
    • public boolean canWrite() 判断文件是否可被写入。
    • public boolean exits() 判断文件是否存在。
    • public long length() 获取文件的长度(单位是字节)。
    • public String getAbsolutePath() 获取文件的绝对路径。
    • public String getParent() 获取文件的父目录。
    • public boolean isFile() 判断文件是否是一个普通文件,而不是目录。
    • public boolean isDirectroy() 判断文件是否是一个目录。
    • public boolean isHidden() 判断文件是否是隐藏文件。
    • public long lastModified() 获取文件最后修改的时间。

10.1.2 目录

File对象调用方法public boolean mkdir()创建一个目录,如果创建成功返回ture。

如果File对象是一个目录,那么该对象调用下述方法列出该目录的文件和子目录。

    • public String[] list() 用字符串形式返回目录下的全部文件。
    • public File [] listFiles() 用File对象形式返回目录下的全部文件。
    • public String[] list(FilenameFilter obj) 用字符串形式返回目录下的指定类型的所有文件。
    • public File [] listFiles(FilenameFilter obj) 用File对象形式返回目录下的指定类型所有文件。
    • 上述两方法的参数FilenameFilter是一个接口,该接口有一个方法:
    • public boolean accept(File dir,String name);

File对象dirFile调用list方法时,需要该方法传递一个实现FilenameFilter接口的对象,list方法执行时,参数obj不断回调接口方法accept(File dir,Stirng name),该方法中的dir为调用list的当前目录dirFile,参数name被实例化为dirFile目录中的一个文件名,当接口方法返回ture时,list方法就将名字name的文件存放返回的数组中。

10.1.3 文件的创建与删除

当使用File类创建一个文件对象后,例如

    • File file=new File("c:\\myletter","letter.txt");
    • 如果c:\myletter目录中没有名字为letter.txt文件,文件对象file调用方法public boolean createNewFile();
    • 文件对象调用方法  public boolean delete()可以删除当前文件,
    • 例如:file.delete(); 

10.1.4运行可执行文件

当要执行一个本地机器上的可执行文件时,可以使用java.lang包中的Runtime类。使用getRuntime静态方法创建对象。

例如:

Runtime ec = Runtime.getRuntime();

ec调用exec(String command)方法打开本地机器上的可执行文件或执行一个操作。

10.2 文件字节输入流

使用输入流通常包括下列4个步骤:

 

    • 设定输入流的源
    • 创建指向流的输入流
    • 让输入流读取源中的数据
    • 关闭输入流

如果对文件读取需求比较简单,那么使用FileInputStream类(文件字节输入流),该类是InputStream类的子类。

构造方法:

FileInputStream(String name)

FileInputStream(File file)

第一个构造方法使用给定的文件夹名name创建FileInputStream流,第二个构造方法使用File对象创建FileInputStream流。

创建输入流时,可能会出现异常,因此必须在try-catch语句的try部分创建输入流创建输入流,在catch(捕获)块检测并处理异常。

使用输入流读取字节

输入流的目的是提供读取源中数据的通道,出现可以通过这个跳刀读取源中的数据。

字节输入流的read的方法以字节为单位读取源中的数据。

  • int read() 读取单个字节的数据,返回字节值(0~255整数),如果未读出字节就返回-1。
  • int read(byte b[]) 读取b.length个字节到字节数组b中,返回实际读取的字节数。如果到达文件的末尾,则返回-1。
  • int read(byte b[], int off, int len) 读取len个字节到字节数组b中,并返回实际读取的字节数目。如果到达文件的末尾,则返回-1,参数off指定从字节数组的某个位置开始存放读取的数据。

FileInputStream流顺序读取文件,只要不关闭流,每次调用read方法就顺序读取源中其余的内容,直到源的末尾或流被关闭。

关闭流:close(),虽然程序结束时,会自动关闭所有流,但显式关闭输入流是一个良好的习惯。

10.3 文件字节输出流

  • 使用输出流通常包括4个基本步骤:

       (1)给出输出流的目的地

       (2)创建指向目的地的输出流

       (3)让输出流把数据写入到目的地

       (4)关闭输出流。

使用FileOutputStream类的下列具有刷新功能的构造方法创建指向文件的输出流。

FileOutputStream(String name);/FileOutputStream(String name,boolean append)

FileOutputStream(File file);/ FileOutputStream(File file,boolean append)

其中:参数name和file指定的文件称为输出流的目的地,append取值为true,输出流不会刷新所指向的文件,而是在文件末尾写入。

第一个构造方法使用给定的文件夹名name创建FileOutputStream流,第二个构造方法使用File对象创建FileOutputStream流。

如果输出流不存在,则创建文件,如果存在,刷新该文件(使文件长度为0)

创建输出流时,可能会出现异常,因此必须在try-catch语句的try部分创建输出流,在catch(捕获)块检测并处理异常。

输出流的write方法以字节单位向目的地写数据。

   void write(int n) 向目的地写入单个字节。

   void write(byte b[]) 向目的地写入一个字节数组。

   void write(byte b[],int off,int len) 从字节数组中偏移量off处取len个字节写到目的地。

void close()关闭输出流,通过调用close()方法,可以保证操作系统把流缓冲区的内容写到它的目的地,即关闭输出流可以把该流所用的缓冲区的内容冲洗掉(通常冲洗到磁盘文件上)。

FileOutputStream流顺序地写文件,只要不关闭流,每次调用write方法就顺序地向目的地写入内容,直到流被关闭。

10.4 文件字符输入、输出流

FileReader、FileWriter字符流(文件字符输入、输出流)

流调用flush()方法可以立刻冲洗当前缓冲区,即将当前缓冲区的内容写入目的地。

10.5 缓冲流

BufferdReader和BufferedWriter类创建的对象称为缓冲输入、输出流。

  • 构造方法:
    • BufferedReader(Reader in);
    • BufferedWriter (Writer out);
  • 2.BufferedReader和BufferedWriter类读写文件的方法:
    • readLine() 读取文本行
    • write(String s,int off,int len) 把字符串s写到文件中
    • newLine(); 向文件写入一个回行符

 

10.6随机流

  • 使用RandomAccessFile类来创建一个随机访问文件流。RandomAccessFile类创建的流的指向既可以作为源也可以作为目的地。    
  • 构造方法:
    • RandomAccessFile(String name,String mode) ;
    • RandomAccessFile(File file,String mode) ;
  • 相关方法:
    • seek(long a)  定位RandomAccessFile流的读写位置
    • getFilePointer() 获取流的当前读写位置 
    • 例子8(把几个int型整数写入到一个名字为tom.dat文件 )
    • readLine()方法在读取含有非ASCII字符的文件时出现“乱码”现象的解决方法:

              1.读取  String str=in.readLine();         

              2.用“iso-8859-1”重新编码   byte b[]=str.getBytes("iso-8859-1");

              3.使用当前机器的默认编码将字节数组转化为字符串

                     String content=new String(b); 

1.字节数组流

  • 字节数组输入流ByteArrayInputStream和字节数组输出流ByteArrayOutputStream分别使用字节数组作为流的源和目标。
  • ByteArrayInputStream构造方法及常用方法
    •   ByteArrayInputStream(byte[] buf);
    •   ByteArrayInputStream(byte[] buf,int offset,int length);
    •   public int read();顺序地从源中读出一个字节
    •   public int read(byte[] b,int off,int len);顺序地从源中读出参数len指定的字节数
  • ByteArrayOutputStream流构造方法及常用方法
    •   ByteArrayOutputStream();
    •   ByteArrayOutputStream(int size);
    •   public void write(int b); 顺序地向缓冲区写入一个字节  
    •   public void write(byte[] b,int off,int len); 将参数b中指定的len个字节顺序地写入缓冲区
    •   public byte[] toByteArray(); 返回输出流写入到缓冲区的全部字节

2.字符数组

    •   CharArrayReader和CharArrayWriter类是字符数组流,使用字符数组作为流的源和目标。例子10   向内存(输出流的缓冲区)写入字符串 。

10.8数据流

  • DataInputStream和DataOutputStream类创建的对象称为数据输入流和数据输出流。
  • 构造方法:
    •    DataInputStream(InputStream in)创建的数据输入流指向一个由参数in指定的底层输入流
    •    DataOutputStream(OutnputStream out)创建的数据输出流指向一个由参数out指定的底层输出流

10.9 对象流

  • ObjectInputStream和ObjectOutputStream类创建的对象称为对象输入流和对象输出流。
  • 它的构造方法是:
    •     ObjectInputStream(InputStream in)
    •    ObjectOutputStream(OutputStream out)
  •  相关方法:
    •      writeObject(Object obj) 将一个对象obj写入到一个文件
    •     readObject() 读取一个对象到程序中 
  • 所谓序列化:一个类如果实现了Serializable接口,那么这个类创建的对象就是所谓序列化的对象。

 

10.10   序列化与对象克隆

  • 如果一个“复制品”实体的变化不会引起原对象实体发生变化,反之亦然。这样的复制品称为原对象的一个克隆对象或简称克隆。
  • 一个对象调用clone()方法就可以获取该对象的克隆对象。
  • 对象输入流通过对象的序列化信息来得到当前对象的一个克隆。 

10.11  使用Scanner解析文件

使用Scanner类和正则表达式来解析文件。

1.使用默认分隔标记解析文件

      创建Scanner对象,并指向要解析的文件,例如:

      File file = new File("hello.java");

      Scanner sc = new Scanner(file);

      sc将空白作为分隔标记

      相关方法  next()依次返回file中的单词

              hasNext()判断file最后一个单词是否已被next()方法返回.

2.使用正则表达式作为分隔标记解析文件 : 创建Scanner对象,指向要解析的文件,并使用useDelimiter方法指定正则表达式作为分隔标记,例如:

    File file = new File("hello.java");

    Scanner sc = new Scanner(file);

    sc.useDelimiter(正则表达式);

    sc将正则表达式作为分隔标记

    相关方法 next()    依次返回file中的单词

            hasNext() 判断file最后一个单词是否已被next()方法返回

10.14   文件锁

  • FileLock、FileChannel类处理Java提供的文件锁功能。它们分别在java.nio和java.nio.channels包中。
  • 输入、输出流读写文件时可以使用文件锁。 
  • RondomAccessFile创建的流在读写文件时使用文件锁的步骤如下:

1.先使用RondomAccessFile流建立指向文件的流对象,该对象的读写属性必须是rw,例如:

                  RandomAccessFile input=new               

                  RandomAccessFile("Example.java","rw");

2.input流调用方法getChannel()获得一个连接到地层文件的FileChannel对象(信道),例如

                  FileChannel channel=input.getChannel();

        3.信道调用tryLock()或lock()方法获得一个FileLock(文件锁)对象,这一过程也称作对文件加锁.

      例如:FileLock lock=channel.tryLock();

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值