950 likes | 1.25k Views
Java 程序设计. Java Programming Spring, 2013. Java I/O. java.io File Class RandomAccessFile Class InputStream & OutputStream Reader & Writer FileInputStream & FileOutputStream FileReader & FileWriter BufferedStream. I/O. 输入 (Input)/ 输出 (Output) 系统,简称为 I/O 系统,
E N D
Java程序设计 Java Programming Spring, 2013
Java I/O • java.io • File Class • RandomAccessFile Class • InputStream & OutputStream • Reader & Writer • FileInputStream & FileOutputStream • FileReader & FileWriter • BufferedStream
I/O • 输入(Input)/输出(Output)系统,简称为I/O系统, • 对于输入/输出问题,Java将之抽象化为流(Stream)对象来解决,对不同的输入/输出问题,提供了相应的流对象解决的方案。 • 流式输入输出的特点是数据的获取和发送沿数据序列的顺序进行,即每一个数据都必须等待排在它前面的数据,等前面的数据读入或送出之后才能被读写。
java.io 包 • java.io包中定义与输入、输出流相关的类和接口,构成了Java语言的I/O框架。 • java.io包中定义的各种各样的输入输出流类,它们都是Object类的直接或间接子类,每一个流类代表一种特定的输入或输出流。 import java.io.*;
流的类结构 java.io包的类层次结构: 以四个顶层抽象类为基础,衍生出系列具体的类来完成各种输入/输出。 InputStream,OutputStream:用于字节的读/写。 Reader,Writer:用于文本(字符)的读/写。 实际使用的是它们的子类的对象。 Object InputStream Reader File OutputStream Writer RandomAccessFile
File handling File类 RandomAccessFile类
File类 • Fundamental class: File • Represents either a file(文件)or a dir(文件夹) location in a file system. • Through its pathname(路径名) • A pathname • Unix: /usr/java/bin/javac • Windows: c:\java\bin\javac
Java文件路径的表示: • Java约定是用UNIX和URL风格的斜线(/)来作路径分隔符; • 如果用Windows/DOS所使用的反斜线( \ )的约定,则需要在字符串内使用它的转义序列( \\ )。 • 例: • c:\\java\\bin\\javac (Windows/DOS) • c:/java/bin/javac (UNIX和URL风格)
Example—separator(分隔符) //显示分隔符 import java.io.*; public class Prova { public static void main(String[] arg) { System.out.println(File.separator+" - "+ File.separatorChar+" - "+ File.pathSeparator+" - "+ File.pathSeparatorChar); } } • Output (in Windows) \ - \ - ; - ; • Output (in Unix): / - / - : - :
File类 • java.io包中的File类提供了获得文件基本信息及文件操作的方法。 • 通过File类,可以建立与磁盘文件的联系;可以用来获取或设置文件或目录的属性,但不支持从文件里读取数据或者往文件里写数据。 • 构造方法 • File(String filename); • File(String directoryPath, String filename); • File(File f, String filename);
Example: • 创建文件和文件夹 //创建文件夹 File file1 = new File("e:/java"); file1.mkdir(); //在目录中创建文件 File file2 = new File(file1,"test.txt"); file2.createNewFile();
File类的常用方法 • 操作文件属性的方法 • public boolean canRead();判断文件是否是可读的。 • public boolean canWrite();判断文件是否可被写入。 • public boolean exists(); 判断文件是否存在。 • public boolean isFile(); 判断文件是否是一个正常文件,而不是目录。 • public boolean isDirectroy();判断文件是否是一个目录。
File类的常用方法 • 获取文件的名称、路径 • public String getName():获取文件的名字。 • public String getPath():得到文件的路径名。 • public String getAbsolutePath():得到文件的绝对路径名。 • public String getParent():得到文件的上一级目录名。
File类的常用方法 • 获取文件处理信息 • public long length(): 获取文件的长度(单位是字节)。 • public long lastModified():获取文件最后修改时间。 • public boolean delete():删除文件。
File类的常用方法 • 目录(directory)操作 • 创建一个名为File的目录: • public boolean mkdir() • 列出目录中的文件 • public String[] list() • public File[] listFiles() • 在目录中创建文件 • public boolean createNewFile()
Example: • //创建文件夹 • File file1 = new File(“e:/java”); //创建File对象 • file1.mkdir();//通过File对象创建文件夹 • //在目录中创建文件 • File file2 = new File(file1,"test.txt"); • file2.createNewFile(); //通过File对象创建文件
//显示文件夹中所有文件的文件名 String[ ] files = file1.list(); for(int i = 0; i<files.length; i++) System.out.print(files[i]); • //显示文件夹中所有文件的对象 • File[ ] files = file1.listFiles(); • for(int i = 0; i<files.length; i++) • System.out.println(files[i].getName()+"\t"+ files[i].length());
Example 1 to test the methods of ‘File’ import java.io.File; public class TryFile { public static void main(String[] args) { // Create an object that is a directory File myDir = new File(“C:/jdk1.5.0/src/java/io”); System.out.println(myDir + (myDir.isDirectory() ? “ is” : “ is not”) + “ a directory.”); // Create an object that is a file File myFile = new File(myDir, “File.java”); System.out.println(myFile + (myFile.exists() ? “ does” : “ does not”) + “ exist”); System.out.println(myFile + (myFile.isFile() ? “ is” : “ is not”) + “ a file.”); System.out.println(myFile + (myFile.isHidden() ? “ is” : “ is not”) + “ hidden”); System.out.println(“You can” + (myFile.canRead() ? “ “ : “not “) + “read “ + myFile); System.out.println(“You can” + (myFile.canWrite() ? “ “ : “not “) + “write “ + myFile); } }
文件的随机访问类(RandomAccessFile) • RandomAccessFile类可以对文件进行随机读写操作。 • 用来访问保存数据记录的文件; • 数据记录是指对应于数据源中一行信息的一组完整的相关信息。 • 例如:
文件的随机访问类(RandomAccessFile) • 定义了对各种数据类型进行读写的方法,如:byte, char, double, float, int, short, long等。 • 可以用getFilePointer()方法获得当前的文件读取指针,可以用seek(long pos)方法访问记录,并进行读写。 • getFilePointer():返回文件指针在文件中的当前偏移量。 • seek(long pos): 设置从文件开头到文件指针的偏移量为pos,在偏移量pos的位置发生下一个读取或写入操作。
文件的随机访问类(RandomAccessFile) 创建一个RandomAccessFile对象 RandomAccessFile(File file, String mode) RandomAccessFile(String name, String mode); • 构造函数可能产生FileNotFoundException及IOException异常 • mode • r:只读; • rw:可读可写 File file=new File(“d:\\lx\\a.txt”); RandomAccessFile rf=new RandomAccessFile( file, ”rw”) ; RandomAccessFile rfile=new RandomAccessFile(“d:\\lx\\a.txt”, ”rw”);
文件的随机访问类(RandomAccessFile) 读写数据的常用方法 读、写基本数据类型: readInt()、writeInt(int n)等; 读取文件中的一行: readLine(); 读、写UTF字符串: readUTF()、writeUTF(String str); UTF-8:8-bit Unicode Transformation Format,一种针对Unicode的可变长度字符编码 。
文件的随机访问类(RandomAccessFile) • 文件随机读写流的读取指针控制 • long getFilePointer(); • 得到当前的文件读取指针。 • void seek(long pos); • 把指针从开始移动到pos位置。 • long length(); • 得到文件的长度(有多少个字节) 。 • void setLength(long newLength); • 重新设置文件的长度。
What is the stream (流) ? • 流是数据的有序序列。 • 流可分为输入流和输出流(按流动方向) : • 输入流指从某个数据来源输入Java应用程序的数据序列, InputStream和Reader处理输入 • 输出流指Java应用程序向某个数据目的地输出的数据序列, OutputStream和Writer处理输出
输出流 输入流 数据源 程序 程序 数据宿 输入流、输出流 • 输入流、输出流分别如下图所示。 输入流示意图 输出流示意图
System类和标准输入输出流 • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。System类在java.lang包中。 • You do not instantiate the System class to use it. • All of System's variables and methods are static variables andstaticcmethods. • To use a class variable, you use it directly from the name of the class using Java's dot (.) notation.
标准流-- System Class //获得运行程序的电脑系统的用户名 class UserNameTest { public static void main(String[] args) { String name; name = System.getProperty("user.name"); System.out.println(“Your name is “ + name); } } • Notice that the program never instantiates a System object. It just references the getProperty method and the out variable directly from the class.
标准流 • System类的3个静态变量就是系统的三个标准流: • System.in:表示系统的标准输入流对象,通常的环境下标准输入流指向键盘输入; • System.out:表示系统的标准输出流对象,通常环境下指向屏幕输出; • System.err:表示系统的标准错误输出流对象,通常环境下也指向屏幕输出。 • 上述三个标准流由系统负责打开关闭,使用时不需要显式地打开或关闭。 • System.out和System.err都用于输出,通常情况下: • Syetem.out用于程序输出一般信息,而System.err用于输出错误信息和其他需要引起用户立即注意的信息。 • 在系统中,System.out具有缓冲机制,而System.err是没有缓冲的,这是两者之间的一个重要区别。
The Standard I/O Streams • Standard Input Stream • System.in-- The System class provides a stream for reading text -- the standard input stream. • Use System.in.read to read the input entered by user. • Standard Output and ErrorStreams • System.out--The standard output stream is typically used for command output. • System.err-- The standard error stream is typically used to display any errors that occur when a program is running. • The print, println, and write Methods • The print and println methods write their String argument to the screen. System.out.println("Duke is not a penguin!"); • The write method is used to write bytes to the stream.
//DataTypePrintTest.java, println方法的重载 • public class DataTypePrintTest { • public static void main(String[] args) { • String stringData = "Java Mania"; • char[] charArrayData = { 'a', 'b', 'c' }; • int integerData = 4; • long longData = Long.MIN_VALUE; • float floatData = Float.MAX_VALUE; • double doubleData = Math.PI; • boolean booleanData = true; • System.out.println(stringData); • System.out.println(charArrayData); • System.out.println(integerData); • System.out.println(longData); • System.out.println(floatData); • System.out.println(doubleData); • System.out.println(booleanData); • System.out.println(); • } • }
//标准输入、输出 import java.io.*; class TranslateByte{ public static void main(String[] args) throws IOException{ byte from=(byte)args[0].charAt(0); byte to=(byte)args[1].charAt(0); int b; while((b=System.in.read())!=-1) //从键盘读入一个byte System.out.write(b==from ? to : b);//输出到屏幕 } } javac TranslateByte.java java TranslateByte b B 输入:abracadabra! 输出:aBracadaBra! Args[1] Args[0]
标准输入输出示例: import java.io.*; public class StandardIO1{ public static void main(String []args) { int ch; System.out.println("请输入一行字符"); try{ //read in a byte from keybord while((ch=System.in.read())!='\r') System.out.write(ch); //写入标准输出流 }catch(IOException e){ System.out.println(e.toString()); } System.out.write('\n'); } }
流的分类 • 字节流和字符流 • InputStream和OutputStream处理8位字节流数据 • Reader和Writer处理16位的字符流数据 • 节点流和处理流(按流的处理位置 ) • 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader 。 • 处理流:使用节点流作为输入或输出。 处理流不直接与数据源或目标相连,而是与另外的流进行配合,对数据进行某种处理,例如: • BufferedReader, • InputStreamReader等。
字符流和字节流 • java.io包中类和接口从功能上主要分为字符流类型和字节流类型 • 字符(character)流是指数据序列的基本构成单位是16位的Unicode字符数据,如:各类基于字符编码的纯文本文件。 • 字节(byte)流是指数据序列的基本构成单位是8位的字节数据,如:各类基于二进制数据的文件、图形图像文件。
文本文件(Text Files,纯字符文件) vs. 二进制文件(Binary Files) • Text file: • 纯文本文件是指的只包含纯文字和字符的文件,这些文字是没有格式的。 • Example: • ASCII (binary)文件: 00110001, 00110010, 00110111 • 记事本文件(.txt文件,默认ANSI编码)。 • Binary file: • 非字符文件,如:图片、声音、word文档。 • 文件含有特殊的格式及计算机代码 。
字节流(Byte Streams) • 字节流可分为输入字节流和输出字节流 • 抽象类InputStream用于表示所有输入字节流 • 抽象类OutputStream用于表示所有输出字节流
Byte Stream family System.in System.err System.out
InputStream类 • 该抽象类作为所有输入字节流类的基类,声明用于读取字节流数据的通用方法。 • public abstract int read() throws IOException; • public int read(byte[] buf, int offset, int count) throws IOException; • public int read(byte[] buf) throws IOException; • public long skip(long count) throws IOException; • public int available() throws IOException; • public void close() throws IOException; • Every method here can throw an IOException; • If a programmer uses any of these methods, he/she must catch IOException (or Exception);
How to do I/O • import java.io.*; • 所有的流类对象在使用前必须打开(即:创建),在使用后必须关闭。 • Open the stream:创建流对象 • Use the stream (read, write, or both) • 通过流对象调用方法 • Close the stream: • 关闭流,释放I/O资源
InputStream类 创建InputStream类对象时,便自动打开了对象所表示的输入流; InputStream所有与输入相关的方法声明抛出异常类IOException InputStream类的对象在完成数据输入后,除标准输入流类对象System.in外,必须调用close方法关闭输入流,通常可将该方法的调用放入finally语句块中
Example: import java.io.*; publicclass StandardIO1{ publicstaticvoid main(String []args) throws IOException { int b; InputStream stdin1= System.in;//声明输入字节流并指向标准输入流 try { b = stdin1.read( ); //使用流,从键盘读入一个字节 System.out.println((char)b); System.out.println(b); stdin1.close(); //关闭流 }catch(IOException ie) { System.out.println(); } } } Output: a a 97
/***** HelloWorld.java *****/ • import java.io.*; • public class HelloWorld { • public static void main( String[ ] args ) { • byte[] ba = new byte[10]; • InputStream stdin = System.in; • System.out.println("Please input a string: "); • try{ • stdin.read(ba); //从键盘读入多个字节 • }catch(IOException ie){ • System.out.println(); • }finally { • } • String s = new String(ba); • System.out.println("The string read in is "+ s); • } • }
OutputStream类 • 当创建OnputStream类对象时,便自动打开了对象所表示的输出流。 • OutputStream所有与输出相关的方法声明抛出异常类IOException • OutputStream类的对象在完成数据输出后,除标准输出流对象System.out外,必须调用close方法关闭输出流
OutputStream类 • 该抽象类作为所有输出字节流类的基类,声明用于输出字节流数据的通用方法: • void write(int b) throws IOException • public void write(byte[] buf, int offset, int count) throws IOException • void write(byte[] b) throws IOException • void flush() throws IOException • void close() throws IOException
OutputStream类 public abstract void write(int b) throws IOException • 将指定的字节写入此输出流。 • write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 • OutputStream 的子类必须提供此方法的实现。 OutputStream stdout = System.out; stdout.write(104); // ASCII ‘h’ ,一个字节 stdout.flush();
字符流(Character Streams) • 字符流可分为输入字符流和输出字符流 • 抽象类Reader用于表示所有输入字符流 • 抽象类Writer用于表示所有输出字符流