IO/输入与输出
- File 类
- RandomAccessFile类
- 各种节点流类
- 字符编码
- 各种过滤流与包装类
- IO类的相关应用
File类
- File类是IO包中唯一代表磁盘文件本身信息类,而不是文件中的内容
- File类定义了一些与平台无关的方法来操作文件,例如:创建、删除文件和重命名文件。
- Java中的目录被当作是一种特殊的文件使用,list方法可以返回目录的所有子目录和文件名。
- 在Unix下的路径分隔符为(/),在Dos下的路径分隔符为(\),java可以正确的处理Unix和Dos路径的分隔符。
编程举例:判断某个文件是否存在,存在则删除,不存在则创建
package blackhouse.advanced;
import java.io.*;
public class FileTest
{
public static void main(String[] args)
{
File f = new File("1.txt");
if (f.exists())
{ f.delete();
} else
{ try
{ f.createNewFile();
} catch (IOException e) {e.printStackTrace();}
}
System.out.println("File name:" + f.getName());
System.out.println("File path:" + f.getPath());
System.out.println("File abs path:" + f.getAbsolutePath());
System.out.println("File Parent:" + f.getParent());
System.out.println(f.exists() ? "exist" : "not exist");
System.out.println(f.canRead() ? "read" : "not read");
System.out.println(f.isDirectory() ? "directory" : "not directory");
}
}
RandomAccessFile 类
- RandomAccessFile类提供了众多的文件访问方法
- RandomAccessFile类支持“随机访问”方式。
- RandomAccessFile类在随机(相对顺序而言)读写等长记录格式文件时有很大的优势。
- RandomAccessFile类仅限于操作文件,不能访问其他的IO设备,如网络,内存映像等。
- 两种构造方法:
- new RandomAccessFile(f,"rw");//读写方式
- new RandomAccessFile(f,"r");//只读方式
编程实例:往文件中写入三名员工的信息,每个员工含有姓名和年龄两个字段,然后安装第二名、第一名、第三名的先后顺序读出员工的信息。
字节流
- InputStream 与OutputStream类
- FileInputStream与FileOutputStream类
- Reader与Writer类
- PipedInputStream与PipedOutputStream类
- ByteArrayInputStream与ByteArrayOutputStream类
- 总是代码的复用性
- 理解流的概念
理解流的概念
- 流是字节序列的抽象概念。
- 文件是数据的静态存储形式,而流是指数据传输时的形态。
- 流类分为两个大类:节点流类和过滤流类(也叫处理流)
InputStream类
程序可以从中连续读取字节的对象叫输入流,在java中,用InputStream类中描述所有输入流的抽象概念
InputStream类的方法
- int read()
- Int read(byte[] b)
- Int read(byte[] b,int off,int len)
- long ship(long n)
- int availble()
- void mark(int readlimit)
- void reset()
- Boolean markSupported()
- void close()
有了垃圾回收器,为什么还要调用close方法?
计算机操作系统所产生的那些东西叫资源,流就是操作系统产生的资源,当程序产生IO流对象的同时,也会创建一个叫流的东西,这个时候在计算机内存里面其实产生了两个东西,一个是java程序的类实例对象,一个是系统本身产生的某种资源,java垃圾回收器只会回收java程序产生的类实例对象,不对回收系统本身产生的资源,所以我们程序自己调用流对象的close()方法去通知系统去释放这个对象所表示的流资源。
OutputStream类
程序可以向其中连续写入字节的对象叫输出流,在java中,用OutputStream类来描述所有输出流的抽象概念。
OutputStream类的方法
- void write(int b)
- void write(byte[] b)
- void write(byte[] b,int off,int len)
- void flush()
- void close()
一个关于IO缓冲区的刻骨铭心的经历!(缓冲区!回忆)
PipedInputStream与PipedOutputStream类
- PipedInputStream类与PipedOutputStream类用于在应用程序中的创建管道通信。
- PipedInputStream与PipedOutputStream类的编程实例
- PipedWriter和PipedReader类
- 使用管道流类,可以实现各个程序模块之间的松耦合通信。
ByteArrayInputStream与ByteArrayOutputStream类
- ByteArrayInputStream和ByteArrayOutputStream,用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
- ByteArrayInputStream的两个构造方法:
- ByteArrayInputStream(byte[] buf)
- ByteArrayInputStream(byte[] buf,int offset,int length)
- ByteArrayOutputStream的两个构造函数:
- ByteArrayOutputStream()
- ByteArrayOutputStream(int)
- StringReader类和StringWriter类来以字符IO流的方式处理字符串
重视IO程序代码的复用
- System.in连接到键盘,是InputStream类型的实例对象。System.out连接到显示器,是PrintStream类的实例对象。
- 不管各种底层屋里设备用什么方式实现数据的终止点,InputStream的read方法总是返回-1来表示输入流的结束。
- 在windows下,按下组合键ctrl+z可以产生输入流的结束标记,在linux下,则是按下ctrl+D组合键。
package blackhouse.advanced.ByteArrayTest;
import java.io.*;
public class ByteArrayTest
{
public static void main(String[] args)
{
String tmp = "abcdefghijklmopqrst";
byte[] src = tmp.getBytes();
ByteArrayInputStream input = new ByteArrayInputStream(src);
ByteArrayOutputStream output = new ByteArrayOutputStream();
transform(input, output);
byte[] result = output.toByteArray();
System.out.println(new String(result));
transform(System.in, System.out);
}
public static void transform(InputStream in, OutputStream out)
{
int ch = 0;
try
{
while ((ch = in.read()) != -1)
{
int upperCh = Character.toUpperCase(ch);
out.write(upperCh);
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
建议:要编程从键盘上连续读取一大段数据时,应尽量将读取数据的过程放在函数中完成,使用-1来作为键盘输入的结束点。在该函数中编写的程序代码不应该使用System.in读取数据,而是用一个InputStream类型的形式参数对象来读取数据,然后将System.in作为实参传递给InputStream类型的形式参数来调用该函数。
包装类的概念与作用
- 通过FileOutputStream对象将一个浮点小数写入到文件中,你感觉有点困难吧?能否通过FileOutputStream对象直接将一个整数写入到文件呢?(write(int b)写入最低字节,用这个方法写入整数也是困难的)
- 假如有个DataOutputStream类提供了王各种输出流对象中写入各种类型的数据(当然包括浮点小数)的方法。你现在所要做的工作就是:传递一个FileOutputStream输出流对象给DataOutputStream实例对象和调用DataOutputStream实例对象的写入浮点小数的方法。
BufferedInputStream与BufferedOutputStream类
- 缓冲流为IO增加了内存缓冲区,增加缓冲区有两个基本目的:
- ---允许java程序依次不只操作一个字节,这样提高了程序的性能。
- ---由于有了缓冲区,使得在流上执行skip、mark和reset方法都成为可能。
- BufferedInputStream与BufferedOutputStream是java提供的两个缓冲区包装类,不管底层系统是否使用了缓冲区,这两个类在自己的实例对象中创建缓冲区。想想这种缓冲区与底层系统提供的缓冲区的区别。(底层系统提供的缓冲区直接与目标系统交换数据,而在包装类中需要调用那个输出流对象将目标数据从对象缓冲区中写入到目标设备,底层系统缓冲区是一次读入或者写入大量数据,)
DataInputStream与DataOutputStream类
- DataOutputStream类提供了三个写入字符串的方法:
- -write Bytes(String s)
- -writeChars(String s)
- -writeUTF(String s)
- 为什么DataInputStream类中有一个readUTF方法,而没有"readBytes"和"readChars"方法呢?
PrintStream类
- PrintStream类提供了一系列得print和println方法,可以将基本数据类型的数据格式化成字符串输出。
- PrintStream对用的PrintWrite类,即使遇到了文本换行符标识符(\n),PintWriter类也不会自动清空缓冲区。
- PrintWriter的println方法能根据操作系统的不同而生成相应的文本换行符。Windows下是“\r\n”,而Linux下的文本换行符是"\n".
ObjectInputStream与ObjectOutputStream类
- 用于从底层输入流中读取对象类型的数据和将对象类型的数据写入到底层输出流
- 所读写的对象必须实现了Serializable接口,对象中的transient和static类型的成员变量不会被读取和写入。
字节流与字符流的转换
- InputStreamReader和OutputStreamWriter,用于将字节流转换成字符流来读写两个类,InputStreamReader可以将一个字节流中的字节解码成字符后读取,OutputStreamWriter将字符编码成字节后写入到一个字节流中。
- 避免频繁的在字符与字节间进行转换,最好不要直接使用InputStreamReader和OutputStreamWrtiter,尽量使用包装类BufferedWriter和BufferedReader类包装。
Java程序与其他进程的数据通信
- 在java中可以用Process类的实例对象来表示子进程,子进程的标准输入和输出不再连接到键盘和显示器,而是以管道流的形式连接到父进程的一个输出流和输入流对象上。
- 调用Process类的getOutputStream和getInputStream方法可以获得连接到子进程的输出流和输入流对象。
- Decorator设计模式
- 在程序中用一个对象(the Decorators)包装另外的一个对象,这是一种被称为Decorator的设计模式。