Java IO操作.doc_第1页
Java IO操作.doc_第2页
Java IO操作.doc_第3页
Java IO操作.doc_第4页
Java IO操作.doc_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京魔乐科技软件学院 联系电话:010-512833461、课程名称:Java IO操作2、知识点2.1、上次课程的主要知识点1、StringBuffer和String类的关系及区别,CharSequence是这两个类所实现的共同的接口;2、Date、SimpleDateFormat、String与Date之间的转换;3、只要是对象数组(多个对象)的比较操作永远都要使用比较器完成 Comparable;4、正则表达式;5、理解通过Class类完成对象的实例化操作。2.2、本次预计讲解的知识点1、File类的使用;2、字节流和字符流的操作;3、内存操作流、打印流、文件流的使用;4、了解字符的编码问题;5、对象序列化的操作。3、具体内容java.io包里面所保存的所有类和接口都是用于IO操作的,此包基本上算是整个java中自学者最痛苦的地方,IO操作并不麻烦,关键是要彻底的理解面向对象中的各个核心概念,在整个的IO操作中记住一句话:“父类定义操作的标准,而具体的操作实现由子类完成”。整个IO操作核心就是五个类一个接口:File、InputStream、OutputStream、Reader、Writer、Serializable;Java的核心重点: 面向对象:都是围绕接口和抽象类; Java集合框架:包含所有的Java数据结构的实现; Java IO:面向对象的各个概念的应用; JDBC:Java数据库操作,现在的程序都是围绕数据库进行的。3.1、File类(重点)java.io.File类是在整个java.io包中最特殊的一个类,表示的是文件本身的若干操作,那么所谓的文件本身指的并不是对文件的内容操作,而是对文件的创建、删除等等这些的操作。File类中提供了如下的几个与文件本身有关的操作方法: 构造方法:public File(String pathname),应该给出要操作文件的路径; 创建文件:public boolean createNewFile() throws IOException; 删除文件:public boolean delete(); 判断文件是否存在:public boolean exists();范例:观察方法的操作package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d:test.txt); / 指定要操作的文件if (file.exists() / 判断文件是否存在file.delete(); / 删除文件 else file.createNewFile(); / 创建文件但是这个时候此程序有以下的几个问题: 问题一:在定义File类对象的时候需要指定一个文件的路径,但是这个路径有分隔符的问题,由于Java属于多操作系统支持,所以每一个所编写的程序必须考虑到操作系统的问题:|- windows之中分隔符是“”;|- linux之中分隔符是“/”为了解决此问题,在File类提供了一个常量:public static final String separatorpackage org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + test.txt); / 指定要操作的文件if (file.exists() / 判断文件是否存在file.delete(); / 删除文件 else file.createNewFile(); / 创建文件 问题二:操作之中会出现延迟的问题,当创建文件或者是删除文件的时候会出现延迟,因为Java的程序都是通过JVM与操作系统间进行交互的,这之中就一定会存在延迟的问题; 问题三:此时是直接在一个硬盘的根目录下创建的新文件,如果说现在要创建的文件有文件夹呢?此时应该先进行文件夹的创建,创建文件夹可以使用:public boolean mkdir()找到指定File的上一级目录:public File getParentFile()package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + iodemo + File.separator+ test.txt); / 指定要操作的文件if (!file.getParentFile().exists() / 判断上一级文件夹是否存在file.getParentFile().mkdir();file.createNewFile(); / 创建文件但是此程序有一个比较麻烦的问题在于此时只能创建一个级别的父文件夹,如果现在的文件夹较多的话,那么就必须采用另外一个方法:public boolean mkdirs()package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定要操作的文件if (!file.getParentFile().exists() / 判断上一级文件夹是否存在file.getParentFile().mkdirs();file.createNewFile(); / 创建文件所以在以后的开发之中肯定要使用mkdirs()方法操作是比较合理的做法。如果现在要想列出一个文件夹中的全部内容,则可以采用以下的方法: 列出所有文件:public String list() 列出所有文件:public File listFiles() 判断给定的路径是否是文件夹:public boolean isDirectory() 判断给定的路径是否是文件:public boolean isFile()范例:先使用list()方法列出package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + testjava); / 指定要操作的文件if (file.exists() / 文件存在if (file.isDirectory() / 是文件夹String all = file.list();for (int x = 0; x all.length; x+) System.out.println(allx);这个时候所列出的只是文件夹或文件的名称而已,如果真的是操作的话,并不方便。范例:使用listFiles()方法列出package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + testjava); / 指定要操作的文件if (file.exists() / 文件存在if (file.isDirectory() / 是文件夹File all = file.listFiles();for (int x = 0; x all.length; x+) System.out.println(allx);很明显,这个操作所返回的是多个File类的对象,所以如果从操作的方便性而言,此方式肯定是最方便的。思考题:要求给定一个文件夹的名称,之后可以将此文件夹中的全部内容进行列出,列出的时候也要列出所有的子文件夹中的内容。此时,根本就不知道本程序需要循环多少次,而唯一的结束条件就是所有的内容都被列出来,只要还有文件就要一直列出,则对于此种代码只能通过递归的方式完成。package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator); / 指定要操作的文件fun(file);public static void fun(File file) if (file.isDirectory() File all = file.listFiles();if (all != null) for (int x = 0; x all.length; x+) fun(allx); else / 没有文件夹了,直接输出System.out.println(file);如果将此代码稍微修改一下,就成恶性程序,把输出换成删除。package org.lxh.demo;import java.io.File;public class IODemo public static void main(String args) throws Exception File file = new File(d: + File.separator + testjava); / 指定要操作的文件fun(file);public static void fun(File file) if (file.isDirectory() File all = file.listFiles();if (all != null) for (int x = 0; x all.length; x+) fun(allx);file.delete();从人道角度而言,肯定不用,但是对付小人有用。3.2、字节流和字符流(重点)File类本身可以操作文件,但是却无法进行文件内容的操作,而如果要想进行文件内容操作的话,则需要使用字节流和字符流两种类型的操作流完成: 字节流:InputStream、OutputStream; 字符流:Reader、Writer;但是不管使用的是何种流,其基本的操作形式是固定的,以进行文件的操作流为例。1、如果要操作的文件则首先通过File类找到一个文件;2、通过字节流或字符流的子类为父类实例化;3、进行读 / 写的操作;4、由于流属于资源操作,操作的最后必须关闭。3.2.1、字节输出流:OutputStreamOutputStream是一个字节的输出流,类的定义如下:public abstract class OutputStreamextends Objectimplements Closeable, Flushable此类是一个抽象类,而且实现了Closeable、Fluashable,这两个接口的定义如下;Closeable:Flushable:public interface Closeablepublic void close() throws IOException ;public interface Flushable public void flush() throws IOException ;由于在OutputStream类之中也提供了close()和flush()两个方法,所以在很多的情况下用户往往不会去关心Closeable和Flushable两个操作接口。在OutputStream类之中定义了如下几个用于输出的方法: 输出全部的字节数据:public void write(byte b) throws IOException 输出部分的字节数据:public void write(byte b, int off, int len) throws IOException 输出单个的字节数据:public abstract void write(int b) throws IOExceptionOutputStream属于字节输出流,所以所有的数据必须都以字节数组的形式输出,但是这里面有一个比较麻烦的问题,OutputStream本身是一个抽象类,那么抽象类要想实例化必须依靠子类,所有的抽象方法由子类负责实现,而且最为重要的是抽象类规定了操作的标准,而由子类决定输出的位置,既然是向文件输出,所以使用:FileOutputStream。 FileOutputStream类的构造:public FileOutputStream(File file) throws FileNotFoundException范例:完成输出的操作package org.lxh.demo;import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (!file.getParentFile().exists() file.getParentFile().mkdirs();OutputStream output = new FileOutputStream(file);String str = Hello World!; / 要输出的数据byte data = str.getBytes(); / 将字符串变为byte数组的形式output.write(data); / 输出数据output.close(); / 关闭流通过运行可以发现字节流的操作特点: 特点一:如果要创建的文件不存在,则在输出之前会自动的为用户创建; 特点二:字节流操作的永远都是字节数组。范例:输出部分的内容output.write(data, 0, 5); / 输出数据但是反复执行程序之后发现有一个问题,就是说现在所有的内容都是新的覆盖掉旧的,能否追加呢?FileOutputStream类的另外一个构造:public FileOutputStream(File file, boolean append) throws FileNotFoundExceptionpackage org.lxh.demo;import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (!file.getParentFile().exists() file.getParentFile().mkdirs();OutputStream output = new FileOutputStream(file, true); / 允许追加String str = Hello World!rn; / 要输出的数据byte data = str.getBytes(); / 将字符串变为byte数组的形式output.write(data); / 输出数据output.close(); / 关闭流但是之前的所有操作都是将所有的字节数组一次性的输出,那么下面使用循环的方式完成输出。for (int x = 0; x data.length; x+) output.write(datax) ;字节流的使用相对而言比较固定,只要有字节数组就可以完成输出。3.2.2、字节输入流:InputStreamInputStream类是专门处理字节输入流的操作类,此类的定义如下:public abstract class InputStreamextends Objectimplements Closeable可以发现本身也是一个抽象类,也实现了Closeable接口,在此类中提供了如下几个读取的方法: 读取数据:public int read(byte b) throws IOException,返回读取的个数,如果没有了则返回-1; 读取部分数据:public int read(byte b, int off, int len) throws IOException,如果没有了则返回-1; 读取单个字节:public abstract int read() throws IOException,如果没有了则返回-1通过对比可以发现InputStream类和OutputStream类中的所有方法是一一对应的,那么既然这个类是一个抽象类,所以要想进行操作,肯定依靠子类:FileInputStream,此类的构造方法如下: 构造方法:public FileInputStream(File file) throws FileNotFoundException范例:读取数据package org.lxh.demo;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (file.exists() / 如果文件存在则进行读取InputStream input = new FileInputStream(file);byte data = new byte1024; / 准备出一个盛水的容器int len = input.read(data); / 将数据向容器中保存System.out.println(文件内容是:【 + new String(data, 0, len) + 】);input.close(); / 关闭流同样,现在如果只是进行部分数据的读取,则可以采用另外一个read()方法完成。int len = input.read(data, 0, 10); / 将数据向容器中保存但是除了这种做法之外,也可以采用read()按照单个字节的形式完成读取。package org.lxh.demo;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (file.exists() / 如果文件存在则进行读取InputStream input = new FileInputStream(file);byte data = new byte1024; / 准备出一个盛水的容器int foot = 0; / 表示读取的长度,同时处理data数组的脚标int num = 0; / 读取的数据do num = input.read(); / 如果不到底,返回的不是-1if (num != -1) datafoot+ = (byte) num; / 保存数据 while (num != -1); / 现在还有内容可以读取System.out.println(文件内容是:【 + new String(data, 0, foot) + 】);input.close(); / 关闭流可是这种写法比较麻烦一些,所以在开发之中可以将以上的代码简化。package org.lxh.demo;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (file.exists() / 如果文件存在则进行读取InputStream input = new FileInputStream(file);byte data = new byte1024; / 准备出一个盛水的容器int foot = 0; / 表示读取的长度,同时处理data数组的脚标int num = 0; / 读取的数据while (num = input.read() != -1) datafoot+ = (byte) num;System.out.println(文件内容是:【 + new String(data, 0, foot) + 】);input.close(); / 关闭流这种写法在实际的开发之中,包括工作上也是使用最多的一种写法,另外,如果说现在觉得开辟数组比较麻烦,那么也可以采用StringBuffer的形式接收。package org.lxh.demo;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (file.exists() / 如果文件存在则进行读取InputStream input = new FileInputStream(file);StringBuffer buf = new StringBuffer(); / 准备出一个盛水的容器int num = 0; / 读取的数据while (num = input.read() != -1) buf.append(char) num);System.out.println(文件内容是:【 + buf + 】);input.close(); / 关闭流同样的操作如果使用了是String的话,则代码的垃圾就太多了,所以StringBuffer就是用于此类情况下的。3.2.3、字符输出流:Writer之前所有的字节流都是以byte数组的形式进行的,而字符输出流肯定操作的字符(字符串、字符数组),Writer类的定义如下:public abstract class Writerextends Objectimplements Appendable, Closeable, Flushable这个类是一个抽象类,这个类的定义形式又和OutputStream一样,但是这个类比OutputStream唯一强在输出: 输出字符串:public void write(String str) throws IOException 输出部分字符串:public void write(String str, int off, int len) throws IOException唯一的方便所有的数据不用再变为byte数组了,而世界输出字符串,那么既然这个类是一个抽象类,则肯定也要依靠子类,文件操作的子类是FileWriter。package org.lxh.demo;import java.io.File;import java.io.FileWriter;import java.io.Writer;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (!file.getParentFile().exists() file.getParentFile().mkdirs();Writer output = new FileWriter(file);String str = Hello World!; / 要输出的数据output.write(str); / 输出数据output.close(); / 关闭流字符输出流比字节输出流唯一的好处就在于中文的处理上,因为一个字符是两个字节,而中文如果使用的是字节处理会出现乱码问题。OutputStream和Wirter类的关系就好比数据库之中的BLOB和CLOB的关系,BLOB可以包含CLOB,但是反过来不行,CLOB只是文字。3.2.4、字符输入流:Reader虽然字符输出流提供了可以将字符串输出的操作,但是这个操作对于输入流可没有,不能说所有的内容直接使用输入按照字符串的形式返回,Reader类的定义结构:public abstract class Readerextends Objectimplements Readable, Closeable读取的时候跟InputStream一样,唯一不同的是使用的是字符数组完成,而且也分为三种,那么既然这个类是抽象类,如果是文件读取则使用FileWriter子类。package org.lxh.demo;import java.io.File;import java.io.FileReader;import java.io.Reader;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (file.exists() / 如果文件存在则进行读取Reader input = new FileReader(file);char data = new char1024; / 准备出一个盛水的容器int len = input.read(data); / 将数据向容器中保存System.out.println(文件内容是:【 + new String(data, 0, len) + 】);input.close(); / 关闭流这四个类其实就只有两个功能,而且使用上都是非常的类似的。3.2.5、字节流和字符流的区别之前通过代码可以发现字节流和字符流在使用上都很相似,那么在实际的开发之中使用那种更好呢?1、字节流和字符流的区别?如果说使用的是字节流则所有的操作直接与终端有关系,而如果是字符流的话,则中间会加入一个缓冲区。那么在输出的时候如果使用的字符流没有关闭,则保存在缓冲区中的数据将无法输出,但是字节流没有此类限制,所以说如果要使用字符流的话不关闭就必须强制刷新缓冲:public abstract void flush() throws IOExceptionpackage org.lxh.demo;import java.io.File;import java.io.FileWriter;import java.io.Writer;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (!file.getParentFile().exists() file.getParentFile().mkdirs();Writer output = new FileWriter(file);String str = Hello World!; / 要输出的数据output.write(str); / 输出数据output.flush(); / 强制刷新缓冲所谓的缓冲就是指一块内存空间,之所以会加入这个过渡,主要的原因是在于程序中可以在这个缓冲里面对一些数据进行处理,例如:中文,会方便一些。如果按照这种方式进行的话,肯定字节流要比字符流快一些,因为属于点到点的操作。2、从文件的存储上来讲。字符流最强的功能是处理文字,但是在整硬盘上所保存的全部内容都是字节数据,像图片、音乐等都属于字节性的数据,那么这个时候使用字节流会更加的方便。所以,综合以上两点,以后就以字节流的操作为主,如果细想的话,可以发现,字节流和字符流在代码的操作形式上基本上是没有区别的,字节流会使了,字符流就一定会使。3.3、字节流和字符流的转换类(理解)既然流分为两大阵营:字节流和字符流,所以在Java类之中有的时候为了方便两种操作流之间的转换,也会提供相应的转换流的操作类: 将字节输出流变为字符输出流:OutputStreamWriter;|- 类的继承如下:java.lang.Object java.io.Writer java.io.OutputStreamWriter|- 构造方法:public OutputStreamWriter(OutputStream out) 将字节输入流变为字符输入流:InputStreamReader;|- 类的继承结构如下:java.lang.Object java.io.Reader java.io.InputStreamReader|- 构造方法:public InputStreamReader(InputStream in)范例:完成这种转换的操作package org.lxh.demo;import java.io.File;import java.io.FileOutputStream;import java.io.OutputStreamWriter;import java.io.Writer;public class IODemo public static void main(String args) throws Exception File file = new File(D: + File.separator + iodemo + File.separator+ hello + File.separator + test.txt); / 指定一个文件if (!file.getParentFile().exists() file.getParentFile().mkdirs();/ 将字节输出流变为字符输出流Writer out = new OutputStreamWriter(new FileOutputStream(file) ;String str = Hello World!; / 要输出的数据out.write(str); / 输出数据out.close(); / 关闭流本程序没有任何的意义,因为即使将字符串变为了字节数组也不麻烦,但是之所以要将转换流的概念提出,主要是有一个原因,观察FileOutputStream和FileInputStream类的继承结构。FileOutputStream:FileInputStream:java.lang.Object java.io.OutputStream java.io.FileOutputStreamjava.lang.Object java.io.InputStream java.io.FilterInputStream可以发现这两个类都属于OutputStream和InputStream的直接子类,但是观察一下FileWriter、FileReader类的继承。FileWriter:FileReader:java.lang.Object java.io.Writer java.io.OutputStreamWriter java.io.FileWriterjava.lang.Object java.io.Reader java.io.InputStreamReader java.io.FileReaderFileWriter不是Wirter的直接子类,而是OutputStreamWriter的直接子类,同理,FileReader也是InputStreamReader类的直接子类,所以从类的继承关系上就可以发现一个特点,本身保存在终端的数据肯定都是字节,而所有的字符都是经过处理后的,而且这里面也增加了一个过渡操作。3.4、思考题(重点)下面使用IO流完成一个文件拷贝命令的实现,例如:Java的类是Copy,输入的路径名称通过初始化参数的形式完成,例如:java Copy 源路径名称 目标路径名称,但是要考虑一些常见的问题。就完成拷贝一个文件的操作,但是要考虑到大数据量文件的问题,例如:要拷贝的文件的数据量有30M以上。需要考虑的判断:1、判断输入的参数是否是两个;2、源文件是否存在;判断完成之后,下面需要进行文件的拷贝操作,所谓的拷贝就是读取和写入。实现形式一:将整个文件读取进来之后一次性写入package org.lxh.demo;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;public class Copy public static void main(String args) throws Exception if (args.length != 2) / 输入的参数不是两个。System.out.println(命令参数有错误。);System.exit(1); / 系统退出File inFile = new File(args0); / 源文件if (!inFile.exists() / 源文件不存在,则退出System.out.println(源文件不存在。);System.exit(1);File outFile = new File(args1); / 输出文件的路径byte data = new byte1024; / 开辟一个数组InputStream input = new FileInputStream(inFile); / 字节输入流OutputStream output = new FileOutputStream(outFile); / 字节输出流int len = input.read(data);output.write(data, 0, len); / 输出数据input.close();output.close();此时的确是完成了复制的功能,但是这种操作使不了,如果现在要复制的文件很大。File outFile = new File(args1); / 输出文件的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论