Java之------IO加强
RandomAccessFile
1、随机访问文件,本身具有读写的方法
new RandomAccessFile()以后,若文件不存在会自动创建,存在则不创建。——该类其实内部既封装了字节输入流,又封装了字节输出流。 该类若用write()方法写整数,每次只写它的最后1个字节。而采取writeInt()方法,则可把1个整数完全地写入。 2、通过skipBytes(int x),seek(int x)来到达随机访问 通过seek方法设置数据的指针就能够实现对文件数据的随机读写。InputStream中的skip()方法只能从头往后跳,不能反向;而seek()方法可双向随意定位。
3、数据修改方面的特点用RandomAccessFile类可以实现数据的修改,固然文件中的数据1般要有规律,以方便在编程时能够进行定位,让数据写对地方。 而用“流”实现数据修改时,则通常需要把数据从流读到数组当中,在数组中进行数据修改,然后再把修改后的数组 再重新写到流中。 序列化 ★ 序列化 将1个对象寄存到某种类型的永久存储器上称为保持。如果1个对象可以被寄存到磁盘或磁带上,或可以发送到另外1台机器并寄存到存储器或磁盘上,那末这个对象就被称为可保持的。(在Java中,序列化、持久化、串行化是1个概念。) ★ 对象图 当1个对象被串行化时,只有对象的数据被保存;方法和构造函数不属于串行化流。如果1个数据变量是1个对象,那末这个对象的数据成员也会被串行化。树或对象数据的结构,包括这些子对象,构成了对象图。 ★ 瞬时 transient 避免对象的属性被序列化。 Address.java
package io.serializable;
import java.io.Serializable;
public class Address implements Serializable {
//静态变量是不会被序列化的。对非静态变量,1般情况下都会被序列化,但如果声明成transient型则不会。
transient int num;//瞬时变量---该变量是不会被序列化的---不会出现在对象图中的
private String name;
private int age;
private String tel;
public Address(String name,int age,String tel) {
super();
this.name = name;
this.age = age;
this.tel = tel;
}
public Address(int num,String name,String tel) {
super();
this.num = num;
this.name = name;
this.age = age;
this.tel = tel;
}
@Override
public String toString() {
return "Address [num=" + num + ",name=" + name + ",age=" + age
+ ",tel=" + tel + "]";
}
} SerializableDemo.java
package io.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class SerializableDemo {
public static void main(String[] args) throws Exception {
//demo1();
demo2();
}
private static void demo2() throws FileNotFoundException,IOException,ClassNotFoundException {
//对象序列化---输出,写
OutputStream fout = new FileOutputStream("a.txt");
ObjectOutputStream out = new ObjectOutputStream(fout);
out.writeObject( new Address(1,"aa",23,"13588888888"));
out.writeObject( new Address(2,"bb",24,"13566666666"));
out.writeObject( new Address(3,"cc","13577777777"));
out.writeObject( new Address(4,"dd",25,"13599999999"));
out.close();
//反序列化----读
InputStream fin = new FileInputStream("a.txt");
ObjectInputStream in = new ObjectInputStream(fin);
System.out.println( in.readObject() );
System.out.println( in.readObject() );
System.out.println( in.readObject() );
System.out.println( in.readObject() );
}
private static void demo1() throws FileNotFoundException,ClassNotFoundException {
//对象序列化---输出,写
OutputStream fout = new FileOutputStream("a.txt");
ObjectOutputStream out = new ObjectOutputStream(fout);
out.writeObject( new Address("aa","13588888888"));
out.writeObject( new Address("bb","13566666666"));
out.writeObject( new Address("cc","13577777777"));
out.writeObject( new Address("dd","13599999999"));
out.close();
//反序列化----读
InputStream fin = new FileInputStream("a.txt");
ObjectInputStream in = new ObjectInputStream(fin);
System.out.println( in.readObject() );
System.out.println( in.readObject() );
System.out.println( in.readObject() );
System.out.println( in.readObject() );
}
} 缓冲输入输出流 (BufferedInputStream和BufferedOutputStream) 方式1:
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream("Test.txt") );
方式2:
DataInputStream in = new DataInputStream(
new FileInputStream("Test.txt") );
方式3:
BufferedInputStream in = new BufferedInputStream(
new DataInputStream(
new FileInputStream("Test.java") );
☆示例测试技术总结:方案1是最优的 1)有buffer比没有更快; 2)buffer放在中间层包装比放在外层更快; 3)按行或按块操作 比 按字节或字符操作更快(用Object流操作的速度 比 字节字符方式 更快) 4)缓冲区要结合流才可使用,在流的基础上对流的功能进行了增强。 package io.buffer;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
public class BufferedStreamDemo {
public static void main(String[] args) {
try {
//test1();
//test2();
test3();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void test1() throws Exception {
long t1 = System.currentTimeMillis();
DataInputStream din = new DataInputStream(new BufferedInputStream(
new FileInputStream("b.txt")));
String str = null;
while ((str = din.readLine()) != null) {
System.out.println(str);
}
long t2 = System.currentTimeMillis();
System.out.println("方式1运行时间(毫秒):" + (t2 - t1));
}
private static void test2() throws Exception {
long t1 = System.currentTimeMillis();
DataInputStream din = new DataInputStream(
new FileInputStream("b.txt"));
String str = null;
while ((str = din.readLine()) != null) {
System.out.println(str);
}
long t2 = System.currentTimeMillis();
System.out.println("方式2运行时间(毫秒):" + (t2 - t1));
}
private static void test3() throws Exception {
long t1 = System.currentTimeMillis();
BufferedInputStream bin = new BufferedInputStream(
new DataInputStream(
new FileInputStream("b.txt")) );
byte buf[] = new byte[20];
int n=0;
while ((n = bin.read(buf)) != ⑴) {
System.out.println(new String(buf,n));
}
long t2 = System.currentTimeMillis();
System.out.println("方式3运行时间(毫秒):" + (t2 - t1));
}
}
(InputStreamReader和OutputStreamWriter) ★转换流功能1:充当字节流与字符流之间的桥梁 需求:摹拟英文聊天程序,要求: 要求1的设计分析: 1)需要从键盘接收录入,得用System.in,它是字节输入流InputStream; 要求2的设计分析: 1)需要把字符数据按行保存到字节流文件 ; package io.transfer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class TranStreamDemo {
public static void main(String[] args) throws IOException {
//输入
InputStream in = System.in;
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
//输出
OutputStream out = new FileOutputStream("chat.txt");
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(osw);
String line = null;
while( (line=br.readLine())!=null){
if("over".equals(line)){//养成好的代码习惯:调用String中的方法时,把常量字符串放在前面,避免变量为null而致使异常
break;
}
System.out.println( line.toUpperCase() );
bw.write(line);
bw.newLine();
bw.flush();//字符流是带缓冲的,必须刷缓冲
}
}
}
★转换流功能2:字符编码转换 采取FileWriter以默许方式编码 采取转换流以默许方式编码 采取转换流以指定编码方式编码 采取转换流以指定编码方式解码 package io.transfer;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class TranStreamDemo2 {
public static void main(String[] args) {
try {
//readTextDecoding1();
//readTextDecoding2();
writeTextEncoding();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void writeTextEncoding() throws IOException {
//第1种: FileWriter+默许编码表
FileWriter fw = new FileWriter("filesw_utf⑻.txt");//该文件的编码由平台(如MyEclipse或dos窗口)定,不1定是utf⑻
fw.write("每天进步1点点...");
fw.close();
//第2种: OutputStreamWriter+默许编码表
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("filesw_utf⑻_2.txt"));//该文件的编码由平台(如MyEclipse或dos窗口)定,不1定是utf⑻
osw.write("第天进步1点点...");//牛耳
osw.close();
//第3种: OutputStreamWriter+指定编码表
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("filesw_utf⑻_3.txt"),"utf⑻");//该文件的编码1定是utf⑻,由于是我们自己指定的
osw2.write("第天进步1点点...");
osw2.close();
}
private static void readTextDecoding1() throws IOException {
FileReader fr = new FileReader("filesutf⑻.txt");//采取默许编码表解码
char[] cbuf = new char[10];
int len=0;
while( (len=fr.read(cbuf))!=⑴){
String str = new String(cbuf,len);
System.out.print(str);
}
fr.close();
}
private static void readTextDecoding2() throws IOException {
//InputStreamReader isr = new InputStreamReader(new FileInputStream("filesgbk.txt"));//如果不指定编码表,则是采取默许的
//用转换流自己指定解码表----只要文件的编码表和这里指定的解码表相同,就不会出现乱码
//InputStreamReader isr = new InputStreamReader( new FileInputStream("filesgbk.txt"),"gbk"); //ok
//InputStreamReader isr = new InputStreamReader( new FileInputStream("filesutf⑻.txt"),"gbk");//乱码
InputStreamReader isr = new InputStreamReader( new FileInputStream("filesutf⑻.txt"),"utf⑻");//ok
char[] cbuf = new char[20];
int len = isr.read(cbuf);
String str = new String(cbuf,len);
System.out.println(str);
isr.close();
}
}
(PrintStream和PrintWriter) ★打印流的特点: 1)只有输出没有输入。PrintStream是字节打印流,PrintWriter是字符打印流。
package io.print;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
//System.out就是PrintStream类型
public class PrintStreamDemo {
public static void main(String[] args) {
try {
demo1();
demo2();
for(int i=0;i<10;i++){
System.out.println(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//把System.out的输出目的地从屏幕更改到日志文件
private static void demo2() throws IOException {
FileOutputStream fout = new FileOutputStream("log.txt");
PrintStream out = new PrintStream(fout,true);
System.setOut(out);
}
private static void demo1() throws IOException {
//
PrintStream out = new PrintStream("print.txt");
//out.write()只写入1个字节的信息,如果参数大于1个字节的范围,那末实际上只会写入最后1个字节的数据
//out.write(97);
out.write(353);//最后1个字节是97,因此写入的是1个字符'a'----写入的是值的表现情势
//System.out.write(353);//输出'a'
//System.out.flush();
out.println(345);//把参数转换成字符串输出
//上1句等价于out.write( String.valueOf(i) )
//※总之,PrintStream中用write()输出的是字节数据且每次只输出1个字节,而print()输出的是数据的值的表现情势即转换成字符串输出。
//JSP中的out对象就是这类类型。要输出字节数据如图片声明等2进制格式则必须用write(),而输出页面数据(字符)则要用print()或println()
}
}
★关于打印流的自动刷新 只有遇到结束字符(换行符)时才会自动刷新,如在调用其中1个println方法或写入换行符或字节('n)时会自动刷新输出缓冲区。 package io.print;
import java.io.IOException;
import java.io.PrintWriter;
//演示PrintStream类的自动刷新功能
public class PrintStreamDemo2 {
public static void main(String[] args) {
try {
//demo1();
demo2();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void demo1() throws IOException {
//默许不自动刷新的
PrintWriter out = new PrintWriter(System.out);
out.print("Hello World");//不会自动刷新
out.println("Hello World");//不会自动刷新
out.flush();//手动刷新
}
private static void demo2() throws IOException {
//设置自动刷新的
PrintWriter out = new PrintWriter(System.out,true);
out.print("Hello World");//不会自动刷新
out.println("Hello World");//会----由于println()内部调用了out.flush()
out.print("Hello3 n");//不会
out.print("Hello3 rn");//不会
out.printf("%s","Hello4");//会
/*总之:
* autoFlush - boolean 变量;如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区。
* ---实际上是由于这几个方法中帮我们调用了out.flush()。
*/
}
}
★字节数组流 ByteArrayInputStream与ByteArrayOutputStream
package io.array;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayStreamDemo {
public static void main(String[] args) {
String str ="adhjsdhhsd";
ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch=0;
while( (ch=bis.read())!=⑴ ){
bos.write(ch);
}
System.out.println(bos.toString());
}
} ★字符数组流CharArrayReader与CharArrayWriter ★字符串流 StringReader 与 StringWriter ★序列流 SequenceInputStream ——对多个流进行合并 将多个流进行逻辑串连(合并变成1个流,操作起来很方便,由于多个源变成了1个源) package io.sequence;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
FileInputStream fin1 = new FileInputStream("filesseq1.txt");
FileInputStream fin2 = new FileInputStream("filesseq2.txt");
FileInputStream fin3 = new FileInputStream("filesseq3.txt");
ArrayList<FileInputStream> v = new ArrayList<FileInputStream>();
v.add(fin1);
v.add(fin2);
v.add(fin3);
Enumeration<FileInputStream> en = Collections.enumeration(v);
SequenceInputStream sis = new SequenceInputStream(en);
//创建输出流---由于要把前3个文件中的内容读取出来合并到 seq4.txt文件
FileOutputStream fos = new FileOutputStream("filesseq4.txt");
int len = 0;
byte buf[] = new byte[10];
while((len=sis.read(buf))!=⑴){
fos.write(buf,len);
}
fos.close();
sis.close();
}
}
IO流知识点小结1、知识点
a、流是用来处理数据的。
b、处理数据时,1定要先明确数据源与数据目的地(数据汇)。
c、数据源可以是文件、键盘或其他流。
d、数据目的地可以是文件、显示器或其他流。 e、流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。 2、IO流体系
使用要点:看顶层(父类共性功能),用底层(子类具体对象)。
命名规律:每一个子类的后缀名都是所属体系的父类的名称,很容易辨别所属的体系。
而且每个子类前缀名都是该子类对象的功能体现。 (掌握IO流体系的要点和规律,开发时设计与查找相应的类就容易多了)
IO流的操作规律1、明确源和目的。
源:InputStream Reader 1定是被读取的。 目的:OutputStream Writer 1定是被写入的。
2、处理的数据是不是是纯文本的数据?是:使用字符流。Reader Writer
否:使用字节流。 InputStream OutputStream (到这里,两个明确肯定完,就能够肯定出要使用哪一个体系。接下来,就应当明确具体这个体系要使用哪一个具体的对象。【所谓的看顶层】) 3、明确数据所在的装备。
源装备: 键盘(System.in) 硬盘(FileXXX)FileReader FileInputStream
内存(数组)ByteArrayInputStream CharArrayReader StringReader
网络(Socket) 目的装备:
显示器(控制台System.out)
硬盘(FileXXX)FileWriter FileOutputStream
内存(数组)ByteArrayOutputStream CharArrayWriter StringWriter
网络(Socket) (到这里,具体使用哪一个对象就能够明确了。【所谓的用底层】) 4、明确是不是需要额外功能? 1) 是不是需要高效?缓冲区Buffered (字符与字节各两个)
2) 是不是需要转换?转换流 InputStreamReader OutputStreamWriter
3) 是不是操作基本数据类型? DataInputStream DataOutputStream
4) 是不是操作对象(对象序列化)? ObjectInputStream ObjectOutputStream
5) 需要对多个源合并吗? SequenceInputStream 6) 需要保证数据的表现情势到目的地吗? PrintStream 或 PrintWriter (到这里,具体的设计方案就能够明确了。【套接与功能加强】)
IO流的操作规律之设计方案练习需求1:复制1个文本文件。 1、明确源和目的。 源:InputStream Reader 目的:OutputStream Writer 2、处理的数据是不是是纯文本的数据? 源:Reader 目的:Writer 3、明确数据所在的装备。 源:file(硬盘) FileReader fr = new FileReader("a.txt"); 目的:file(硬盘) FileWriter fw = new FileWriter("b.txt"); 4、明确是不是需要额外功能? BufferedReader bufr = new BufferedReader(new FileReader("a.txt")); BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
需求2:复制1个图片文件。
1、明确源和目的。 源:InputStream Reader 目的:OutputStream Writer 2、处理的数据是不是是纯文本的数据? 源:Reader 目的:Writer 3、明确数据所在的装备。 源:file(硬盘) FileReader fr = new FileReader("a.txt"); 目的:file(硬盘) FileWriter fw = new FileWriter("b.txt"); 4、明确是不是需要额外功能? BufferedReader bufr = new BufferedReader(new FileReader("a.txt")); BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
需求3:读取键盘录入,存储到1个文件中。
1、明确源和目的。 源:InputStream Reader 目的:OutputStream Writer 2、处理的数据是不是是纯文本的数据? 源:Reader 目的:Writer 3、明确数据所在的装备。 源:file(硬盘) InputStream in = System.in; 缘由:必须要将键盘录入的字节转成字符。需要将字节-->字符的转换流。InputStreamReader 目的:file(硬盘) FileWriter fw = new FileWriter("b.txt"); 4、明确是不是需要额外功能? InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("a.txt"); 高效:BufferedReader bufr = new BufferedReader( isr); BufferedWriter bufw = new BufferedWriter( fw );
需求4:读取1个文本文件,显示到显示器上。
1、明确源和目的。 源:InputStream Reader 目的:OutputStream Writer 2、处理的数据是不是是纯文本的数据? 源:Reader 目的:Writer 3、明确数据所在的装备。 源:file(硬盘) FileReader fr = new FileReader("a.txt"); 目的:显示器 OutputStream out = System.out; 缘由:要将字符数据转换成字节输出。输出转换流:OutputStreamWriter 4、明确是不是需要额外功能? FileReader fr = new FileReader("a.txt"); OutputStreamWriter osw = new OutputStreamWriter(System.out); 高效:BufferedReader bufr = new BufferedReader( fr);
BufferedWriter bufw = new BufferedWriter( osw );
需求5:读取1个文本文件,将文本依照指定的编码表UTF⑻写入到另外一个文件中
1、明确源和目的。 源:InputStream Reader 目的:OutputStream Writer 2、处理的数据是不是是纯文本的数据? 源:Reader 目的:Writer 3、明确数据所在的装备。 源:file(硬盘) FileReader fr = new FileReader("a.txt"); 目的:file(硬盘) FileOutputStream fout = new FileOutputStream("b.txt")缘由:假定输出时要为字符数据指定编码表。转换流中的参数需要字节流,因此用转换流:FileOutputStream。 4、明确是不是需要额外功能? FileReader fr = new FileReader("a.txt"); OutputStreamWriter osw = new OutputStreamWriter(fout,”utf⑻”); 高效:BufferedReader bufr = new BufferedReader( fr); BufferedWriter bufw = new BufferedWriter( osw ); 两大例题文件切割
点击打开链接
字符串截取
点击打开链接
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |