IO学习笔记
1、 File类
File类是IO包中唯一代表磁盘文件本身信息的类,而不是文件中的内容。File类还定义了一些与平台无关的方法来操纵文件。
常用的方法:canRead() canWrite() delete() exists() getAbsolutePath() getName() getPath() isDirectory() lastModified() list() setReadOnly()等。
Java中的目录被当作一种特殊的文件使用,list方法可以返回目录中的所有子目录和文件名。
File file = new File("E:\\java");
String [] str = file.list();
for(int i =0 ;i< str.length;i++){
System.out.println(str[i]);
}
此段代码打印出E:\java目录下的所有子目录文件名。
2、 RandomAccessFile类
RandomAccessFile类仅限于操作文件,不能访问其他的IO设备,如:网络,内存映像等。该类在读取等长记录格式的文件有很大的优势。提供了多种访问文件的方法。它还支持随机访问方式,可以跳转到任意位置开始读写数据。
构造方法:
RandomAccessFile(File file, String mode)
RandomAccessFile(String name, String mode)
Mode
的含义:
"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于"rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。
RandomAccessFile实例对象中有个指示器,可以通过以下方法,调整指示器的位置。
即:相对跳转:skipBytes(int n) 绝对跳转:seek(long pos)
看完视频后,我觉得选择数据写入的适当方式,对正确的操作数据有很大的帮助,譬如说数据中有汉字的情况,我们就不能按字节的方式来把数据写入到文件中去,我们可以考虑用写字符的方式来写汉字。
3、 节点流
FileInputStream和FileOutputStream
package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class TestFileInputStream {
/**
* 用FileOutputStream类向文件中写入一个字符串,然后用FileInputStream读出写入的内容。
*
* 这两个类是对字节的操作,操作很受限制,调用write方法写入的字节数组或是一个字节。
* 同样调用read方法时,读取到的数据也存储到字节数组中,再将字节数组转换为字符串。
*/
public static void main(String[] args) {
File f = new File("A.txt");
byte [] b = new byte[1024];
int len = 0;
String str = "";
try {
//如果文件已经存在,则覆盖文件,如果文件没有存在,则创建文件写入数据。
FileOutputStream fos = new FileOutputStream(f);
//将要写入的字符串转换为字节数组再写入。
fos.write(new String("jack in IO.").getBytes());
//此处需要注意的是:OutputStream的写入一个字节的write方法,内部不会自动调用flush方法刷新缓冲区
//当时写入一个字节数组的write方法他会自动调用flush方法,把缓冲区中的数据写入到文件中。
//养成关闭流的习惯。
fos.close();
//如果文件没有存在,则抛出IOException。
FileInputStream fis = new FileInputStream(f);
//记录读取到得字节长度,最大可以为b.length,没有读取到时为-1.
len = fis.read(b);
//将字节数组转换为字符串。
str = new String(b,0,len);
System.out.println(str);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FileReader和FileWriter
package io;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileReader {
/**
* 用FileWriter类向文件中写入一个字符串,然后用FileReader读出写入的内容。
*
* 这两个类是对字符的操作,操作较方便了,调用write方法可以直接写入一个字符串了。
* 同样调用read方法时,读取到的数据也存储到字符数组中,再将字符数组转换为字符串,不是很方便。
*/
public static void main(String[] args) {
File f = new File("b.txt");
char c[] = new char[4];
//char c[] = new char[1024];
String str = "";
try {
FileWriter fw = new FileWriter(f);
//可以直接写入一个字符串
fw.write("Jack is the best Student!");
/*
* 注意刷新缓冲区 fw.flush();
* FileWriter的write不会自动调用flush方法,故我们必须手动的调用close方法,
* 把缓冲区中的数据写入到文件中*/
fw.close();
FileReader fr = new FileReader(f);
/*读取字符数组
* 此处我没有再定义一个较大的字符数组,而是只定义了一个长度为4的字符数组
* 通过判断是否已读完文件,反复读取。
* 这种思想符合实际,实际中文件可能很大,我们不可能一次就能把数据读到字符数组中
* 我们得通过多次的读取,才能把这个较大的文件读完。
*/
while(fr.read(c)!= -1){
str = new String(c);
System.out.print(str);
//重新创建一个字符数组很重要,应为c中有上次数据的残留。
c = new char[4];
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4、 管道流
PipedOutputStreamPipedInputStream 和PipedWriter PipedReader
可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。通常,数据由某个线程写入PipedOutputStream
对象,并由其他线程从连接的 PipedInputStream
读取。不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。使用管道流类可以实现各个模块之间的高内聚低耦合。
用2个线程模拟管道流之间的通信。
管道发送端:以发送字符的形式发送信息。package io.PipedStream;
import java.io.IOException;
import java.io.PipedWriter;
public class SenderWriter extends Thread{
private PipedWriter pfw = new PipedWriter();
public PipedWriter getWriter(){
return pfw;
}
public void run(){
String str = new String("Hello,I'm Jack!");
try {
pfw.write(str);
pfw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
管道接收端:就收发送端的信息。
package io.PipedStream;
import java.io.IOException;
import java.io.PipedReader;
public class ServerReader extends Thread{
private PipedReader pr = new PipedReader();
public PipedReader getReader(){
return pr;
}
public void run(){
char []c = new char[1024];
int len = 0;
try {
len = pr.read(c);
System.out.println("From the Sender:" + new String(c,0,len));
pr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
启动管道线程:
package io.PipedStream;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
public class TestPipedReader {
public static void main(String[] args) {
SenderWriter sw = new SenderWriter();
ServerReader sr = new ServerReader();
PipedWriter pw = sw.getWriter();
PipedReader pr = sr.getReader();
try {
pw.connect(pr);
sw.start();
sr.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5、 ByteArrayInputStream和ByteArrayOutputStream
用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
6、 StringReader和 StringWriter
以字符IO流的方式类处理字符串。
7、 System.in和 System.out
在Windows下,按下Ctrl+Z组合键可以产生键盘输入流的结束标记,在linux下,则是按下Ctrl+D组合键来产生键盘输入流的结束标记。
8、 字符编码
Gb2312 GBK ASCII Unicode UTF-8 UTF-16
9、 ObjectOutputStream和ObjectInputStream
这两个包装类,用于从底层输入流中读取对象类型的数据和将对象类型的数据写入到底层输出流。ObjectOutputStream和ObjectInputStream类所读写的对象必须实现Serializable接口。对象中的transient和static类型的成员变量不会被读取和写入。
package io;
import java.io.Serializable;
public class Student implements Serializable{
int id;
String name;
int age;
String department;
public Student(int age, String department, int id, String name) {
this.age = age;
this.department = department;
this.id = id;
this.name = name;
}
}
package io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectStreamTest {
/**
* 创建可序列化的学生对象,并用ObjectOutputStream类把它存储到一个文件中,
* 然后再用ObjectInputStream类把存储的数据读取到一个学生对象中,即恢复保存的学生对象。
*/
public static void main(String[] args) throws Exception {
//创建2个学生对象
Student stu1 = new Student(22,"mathematic",01,"jack");
Student stu2 = new Student(21,"accounting",02,"lucy");
//将学生对象写入到student.txt中
FileOutputStream fos = new FileOutputStream("student.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(stu1);
oos.writeObject(stu2);
oos.close();
//从student.txt中读取学生对象
FileInputStream fis = new FileInputStream("student.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Student s1 = (Student) ois.readObject();
Student s2 = (Student) ois.readObject();
ois.close();
//打印学生信息
System.out.println("id = " + s1.id);
System.out.println("name = " + s1.name);
System.out.println("age = " + s1.age);
System.out.println("department = " + s1.department);
System.out.println("id = " + s2.id);
System.out.println("name = " + s2.name);
System.out.println("age = " + s2.age);
System.out.println("department = " + s2.department);
}
}
10、 字节流和字符流之间的转换
InputStreamReader和OutputStreamWriter是用于将字节流转换成字符流来读写的两个类,InputStreamReader可以将一个字节流中的字节解码成字符后读取,OutputStreamWriter将字符编码成字节后写入到一个字节流中。
避免频繁的在字符和字节间进行转换,最好不要直接使用InputStreamReader和OutputStreamWriter来读写数据,应尽量使用BufferedWriter类包装OutputStreamWriter,用BufferedReader类包装InputStreamReader.
11、 键盘输入
//方法一
BufferedReader br =newBufferedReader(newInputStreamReader(System.in));
String str1 = br.readLine();
//方法二
Scanner san = new Scanner(System.in);
String str2 = san.nextLine();
12、 Decorator设计模式
在程序中用一个对象包装另一个对象,这是一种被称为Decorator的设计模式。
如果需要设计自己的IO包装类,这个类需要继承以FilterXXX命名的类。
---------------------- android培训、java培训、期待与您交流! ---------------------- 详细请查看:http://edu.csdn.net/heima