
InputStream 是所有的输入字节流的父类,它是一个抽象类。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。
PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。
意思是FileInputStream类可以通过一个String路径名创建一个对象,FileInputStream(String name)。
而DataInputStream必须装饰一个类才能返回一个对象,DataInputStream(InputStream in)。
1. int read( ); //读取一个字节,返回值为所读的字节 对应的AsII编码
2. int read( byte b[ ] ); //读取多个字节,放置到字节数组b中,通常读取的字节数量为b的长度,返回值为实际读取的字节的数量
3. int read( byte b[ ], int off, int len ); //读取len个字节,放置到以下标off开始字节数组b中,返回值为实际读取的字节的数量
4. int available( ); //返回值为流中尚未读取的字节的数量
5. long skip( long n ); //读指针跳过n个字节不读,返回值为实际跳过的字节数量
6. close( ); //流操作完毕后必须关闭
7. available( ) 返回此输入流下一个方法可以读取的字节数。
◇ 使用输入流中的标记:
void mark( int readlimit ); //记录当前读指针所在位置,readlimit 表示读指针读出readlimit个字节后所标记的指针位置才失效
void reset( ); //把读指针重新指向用mark方法所记录的位置
boolean markSupported( ); //当前的流是否支持读指针的记录功能
2.OutputStream 输出数据:
OutputStream 是所有的输出字节流的父类,它是一个抽象类。
ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,
ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。具体例子跟InputStream是对应的。
1. void write( int b ); //往流中写一个字节b
2. void write( byte b[ ] ); //往流中写一个字节数组b
3. void write( byte b[ ], int off, int len ); //把字节数组b中从下标off开始,长度为len的字节写入流中
4. ◇ flush( ) //刷空输出流,并输出所有被缓存的字节,由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
5. close( ); //流操作完毕后必须关闭
1.内存流
public static void main(String[] args) throws IOException {
/*字节数组
* ByteArrayInputStream
* ByteArrayOutputStream
* 字符数组
* CharArrayReader
* CharArrayWriter
* */
//字节数组输入流对象
/* byte [] b = {97,98,99,100,101,97,98,99,100,101}; //源数组对象(源文件对象)
ByteArrayInputStream bais = new ByteArrayInputStream(b);
//只读一次
// int a = bais.read();
// System.out.println(a); //97
//一次读完
// byte [] piao = new byte[bais.available()];
// System.out.println(bais.available()); //10
// bais.read(piao);
// System.out.println(Arrays.toString(piao));
//循环读
byte [] piao = new byte[4];
int len = -1;
while((len = bais.read(piao))!=-1){
System.out.print(new String(Arrays.copyOf(piao, len)));
for(byte c:Arrays.copyOf(piao, len)){
System.out.print(c+" ");
}
}
*/
//字节数组输出流对象
/* byte [] b = new byte[1000];
//将程序的字节数组中 的数组 写入 字节流里
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = {97,98,99,100,101,97,98,99,100,101};
bos.write(data,0,data.length);
System.out.println(bos.toString()); //abcdeabcde
System.out.println(Arrays.toString(bos.toByteArray()));//[97, 98, 99, 100, 101, 97, 98, 99, 100, 101]
FileOutputStream fos = new FileOutputStream("aa.txt");
bos.writeTo(fos); //将字节数组输出流中的数据 写入文件输出流中 //// abcdeabcde
fos.write(50); // abcdeabcde2 ,把2也写进去
*/
//字符数组输入流对象
/* char [] ch = {‘A‘,‘Z‘,‘C‘,‘D‘,‘a‘};
CharArrayReader car= new CharArrayReader(ch);
//只读一次
// int a = car.read();
// System.out.println(a);//65
//一次读完
// char[] piao = new char[ch.length];
// car.read(piao);
// for(char c:piao){
// System.out.print(c+" "); //A Z C D a
// }
//循环读
char [] piao = new char[3];
int len = -1;
while((len = car.read(piao))!=-1){
System.out.print(new String(Arrays.copyOf(piao, len)));
for(char c:Arrays.copyOf(piao, len)){
System.out.print(c+" "); //AZCA Z C DaD a
}
}
*/
//字符数组输出流对象
CharArrayWriter caw = new CharArrayWriter();
char [] ch = "我们好".toCharArray();
caw.write("你好,我好,啦啦啦");
caw.append("么么哒"); //CharSequence 接口
caw.flush();
//System.out.println(caw.toString());//你好,我好,啦啦啦么么哒
// for(char b:caw.toCharArray()){
// System.out.print(b);
// }
FileWriter fw = new FileWriter("tt.txt");
caw.writeTo(fw);
fw.write("");
fw.flush(); //你好,我好,啦啦啦么么哒
}
}
2.文件流
FileInputStream 从本地文件中读取数据 从硬盘存在的一个文件中,读取其内容到程序中。使用FileInputStream ,要读取的文件一定要存在。否则抛FileNotFoundException FileOutputStream 向本地文件中写入数据 创建一个File对象,表明要写入的文件位置。输出的物理文件可以不存在,当执行过程中,若不存在,会自动的创建。若存在,会将原有的文件覆盖
public static void main(String[] args) throws IOException {
/* 文件流
文件字节流: FileInputStream ,FileOutputStream
文件字符流: FileReader, FileWriter
*/
//FileInputStream 文件字节输入流 //从本地文件中读取数据
//FileOutputStream 文件字节输出流 //向本地文件中写入数据
FileInputStream fis = new FileInputStream("aa.txt");
File f2 = new File("bb.txt");
FileOutputStream fos =new FileOutputStream(f2);
/* //方法一:
byte[] b = new byte[(int)f1.length()];
fis.read(b);
fos.write(b);
*/
//方法二
byte[] b = new byte[89];
while(fis.available()>0){
int len = fis.read(b); //先读数据到数组中
fos.write(Arrays.copyOf(b, len)); //将b数组的数据写到目标文件中
}
// FileReader 文件字符输入流
//目标文件
FileReader fr = new FileReader("hello.txt"); //aa123456789zxcvbnm
/* //只读一次:
int ch1 = fr.read();
System.out.println(ch1); //97
//一次读完
char[] ch2 = new char[50];
int len = fr.read(ch2);
System.out.println(len); //23
*/
//循环读
char[] ch3 = new char[10];
int len1 = -1;
while((len1=fr.read(ch3))!=-1){
System.out.println(new String(Arrays.copyOf(ch3, len1)));
}
// 输出结果:
// aa12345678
// 9zxcvbnm
//FileWriter 文件字符输出流
File f = new File("world.txt");
//创建文件字符输出流对象
FileWriter fw = new FileWriter(f,true);// true 表示写入数据时是否可以拼接。false 表示覆盖
fw.write("你好呀呀呀呀");
char[] cbuf = "323你好丫丫33".toCharArray();
fw.write(cbuf); //你好呀呀呀呀323你好丫丫33
fw.flush();//手动刷新
}
3.缓冲流
例如 :文件流程序 直接 操作磁盘文件 和 内存操作节点设备,如果频繁操作 效率低下。
缓冲流,可以把读写的数据线存储在缓冲区中,然后在适当的时候刷新(提交)到节点设备中,减少了操作次数
public static void main(String[] args) throws IOException {
/*
缓冲流: 包装其他的流,达到高校的读写
BufferedInputStream 带有缓冲区的字节输入流
BufferedOutputStream 带有缓冲区的字节输出流
BufferedReader 带有缓冲区的字符输入流
BufferedWriter 带有缓冲区的字符输出流
*/
/*
//BufferedInputStream 带有缓冲区的字节输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aa.txt")); //abcdeabcde2
byte [] b = new byte[5];
int len = -1;
while((len=bis.read(b))!=-1){
System.out.println(new String(Arrays.copyOf(b, len)));
}
// 输出结果: abcde
// abcde
// 2
*/
/*
//BufferedOutputStream 带有缓冲区的字节输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("yy.txt"));
bos.write("你好呀".getBytes()); //你好呀
bos.flush();
*/
//BufferedReader 带有缓冲区的字符输入流
/* BufferedReader br = new BufferedReader(new FileReader("aa.txt"));
char[] ch = new char[4];
//System.out.println(br.readLine()); //abcdeabcde2 一次读一行数据,如果读不到返回为空
String s = null;
while((s = br.readLine()) != null){//一行一行的读
System.out.println(s);
}
*/
//BufferedWriter 带有缓冲区的字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("zz.txt"));
bw.write("今天天气好好\n"); // \n 表示换行
bw.append("好吗");
bw.newLine(); //表示换行
bw.append(‘好‘);
bw.flush();
// 输出结果:今天天气好好
// 好吗
// 好
}
}
4.对象流
public class Student implements Serializable {
private String name;
private int id;
private int age;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public int getAge() {return age;}
public void setAge(int age) { this.age = age;}
public Student(String name, int id, int age) {
super();
this.name = name;
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", id=" + id + ", age=" + age + "]";
}
}
public static void main(String[] args) throws Exception {
Student student = new Student("aa",1434,12);
File file = new File("student.txt");
FileOutputStream fos = new FileOutputStream(file);
//创建对象输出流 步骤:把 数据输出流对象 作为 对象输出流对象的 参数?
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.flush();//手动刷新
oos.writeObject(student);//将对象数据写入到Student.txt文件中 //writeObject :进行对象序列化操作
/*需要注意的细节:
* 1.如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口。 Serializable接口没有任何的方法,是一个标识接口。
* 2.对象以对象流形式保存时需要进行序列化操作
*/
//后开先关原则
oos.close();
fos.close();
//创建对象输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("student.txt")));
Object o = ois.readObject();//读操作 //readObject() 反序列化操作:
System.out.println(o); // Student [name=aa, id=1434, age=12]
}
}
5.打印流
System.out 是一个特殊的 PrintStream “标准”输出流 : 输出结果到控制台
System.err 是一个特殊的 PrintStream "标准"错误输出流 : 输出到控制台,在Eclipse中显示红色的
System.in 是一个特殊的InputStream "标准"输入流 : 数据源来至控制台输入
重定向 : 例如System.out 把数据输出到控制台,通过重定向可以改变输出的目的地 重定向的方法调用代码 必须写在打印或者输入的前面
System中提供对应的重定向的方法:
static void setErr(PrintStream err) 重新分配“标准”错误输出流。
static void setIn(InputStream in) 重新分配“标准”输入流。
static void setOut(PrintStream out) 重新分配“标准”输出流。
public static void main(String[] args) throws IOException {
/* PrintStream 字节打印流
* PrintWriter 字符打印流
*/
PrintStream ps = new PrintStream(new FileOutputStream("m.txt"));
ps.print("nihao");
ps.append("shao");
ps.flush(); // nihaoshao
PrintWriter pw = new PrintWriter(new FileWriter("n.txt"));
pw.printf("你叫%s年龄是%d", "张三",18); // %s 表示拼接String 类型的值 %d 表示拼接int 类型的值
pw.println();
pw.append("好的");
pw.flush();
/* 输出结果:
你叫张三年龄是18
好的
*/
// 标准输入输出流以及标准错误输出流
System.err.println("变红了"); //打印红色字体
System.out.println("请输入一个字符:");
int ch = System.in.read();
System.out.println(ch);
/*
变红了
请输入一个字符:
2
50
*/
//重定向
PrintStream ps1 = new PrintStream(new FileOutputStream("mmm.txt"));
System.setErr(ps1); //重定向到指定文件中保存
System.err.print("你好");
}
}
7 .文本扫描器Scanner
1. 相当于一个输入流 , Java.util.Scanner 位于 util 包下。没有拓展至IO流的4个基本的抽象类,而是Object ,实现了Iterator(迭代器)接口 ,抛出 throws FileNotFoundException 。
2. Scanner文本扫描器,可以读取哪些数据?
Scanner(File source) :扫描的指定的文件
Scanner(InputStream source) :扫描指定的输入流
Scanner(String source) :扫描指定的字符串
3. 常用的方法
1:public boolean hasNextXXX():判断是否有指定类型数据,如果没有指定类型则为String
2:public XXX nextXXX():取得指定类型的数据,如果没有指定类型则为String
3:public Scanner useDelimiter(Pattren pattern):自定义分隔符
public static void main(String[] args) throws FileNotFoundException {
//1. 从文件中读取数据
// next() 遇到空白字符换行 nextLine() 遇到空白字符不换行,一行一行的读。
/* Scanner sc = new Scanner(new File("aa.txt"));
while(sc.hasNextLine()){
System.out.println(sc.nextLine());
}
while(sc.hasNext()){ // Scanner 自带迭代器
System.out.println(sc.next());
}
while(sc.hasNextInt()){
System.out.println(sc.nextInt());
}
*/
/*2. 从输入流中读取数据 (system.in 从控制台读取)
Scanner sc1 = new Scanner(new FileInputStream("aa.txt"));
while(sc.hasNextLine()){
System.out.println(sc.nextLine());
}
*/
//3. 从字符串中读取数据
Scanner sc2 = new Scanner("ab hao\tworld\n hello fs\tworld\n fs\tworld\n");
System.out.println(sc2.nextLine());
while(sc2.hasNextLine()){
System.out.println(sc2.nextLine());
}
//4. 使用自定义分隔符
Scanner sc3 = new Scanner("hello d-d-d-world-enen");
sc3.useDelimiter("-"); //以"-" 作为分割符,所以下面next()方法就不会以空格作为换行了。
while(sc3.hasNext()){
System.out.println(sc3.next());
}
}
}
8.. 随机访问文件RandomAccessFile
RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件
支持只访问文件的部分内容
可以向已存在的文件后追加内容
RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile 类对象可以自由移动记录指针:
long getFilePointer():获取文件记录指针的当前位置
void seek(long pos):将文件记录指针定位到 pos 位置
构造器
public RandomAccessFile(File file, String mode)
public RandomAccessFile(String name, String mode)
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:
r: 以只读方式打开
rw:打开以便读取和写入
rwd:打开以便读取和写入;同步文件内容的更新
rws:打开以便读取和写入;同步文件内容和元数据的更新
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("a.txt"),"rw");
//raf.write("javaee.hello".getBytes()); //指针默认在开始的位置 去替换
raf.seek(raf.length()); //设置和指针到文件的末尾处
raf.write("走你".getBytes()); //在末尾处添加
}
原文:https://www.cnblogs.com/gshao/p/10158938.html