java常用数据流应用实例解析
人气:0这篇文章主要介绍了java常用数据流应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
按操作单位的不同分为:字节流(8bit)(InputStream、OuputStream)、字符流(16bit)(Reader、Writer)
按数据流的流向不同分为:输入流、输出流
按角色的不同分为:节点流、处理流
一、不带缓冲的流
1.文件字节输入流、文件字节输出流
package anno; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Test2 { public static void main(String[] args) { test1FileInputStream(); test2FileInputStream(); testFileOutputStream(); } public static void test1FileInputStream() { String path = "F:\\test.txt"; try { FileInputStream fs = new FileInputStream(path); //设置一个数组接收文件的内容 //需要注意的是,如果数组设置的太小,那么可能出现读取的数据不完整或者乱码等情况 byte[] b = new byte[30]; //文件输入流对象有一个返回值,返回的是读取数据的长度,如果读取到一个数据了,还会向后读一个, //当读取完毕时会返回-1 int len = 0; while((len=fs.read(b))!=-1) { //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度 System.out.println(new String(b, 0, len)); } fs.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void test2FileInputStream() { String path = "F:\\test.txt"; File f = new File(path); int l = (int) f.length(); try { FileInputStream fs = new FileInputStream(path); byte[] b = new byte[l]; //将读取的数据存入到b中 fs.read(b); //将b转换成字符串并输出 System.out.println(new String(b)); fs.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void testFileOutputStream() { //如果不存在该文件,则系统会新建一个 String path1 = "F:\\test2.txt"; try { FileOutputStream fo = new FileOutputStream(path1); String str = "这是我测试的输入"; fo.write(str.getBytes());//将数据写到byte中 fo.flush();//将内存中的数据写到文件中 fo.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
在运行的过程中会遇到一些问题,比如说设置的byte数组来接收读取的数据,如果初始化长度给的比较小,那么读取的数据就不全,在进行test1FileInputStream()的实验中,即使按照:
int len = 0; while((len=fs.read(b))!=-1) { //参数1是缓冲数据数组,参数2是从哪个位置开始转换成字符串,参数3是总共转换的长度 System.out.println(new String(b, 0, len)); }
进行输出,如果byte设置的还是太小,就会出现:
这是我新建的test.txt�
��件
这种乱码问题,于是进行了第二种方法的尝试,即在传入数据之前首先获得要接收多少字节的数据,然后在进行接收(借鉴之前在golang中文件读取并显示的思想),然后就没有问题了,即test2FileInputStream()。
输出结果:
这是我新建的test.txt文件
2.使用字节流将一个文件复制到指定的文件夹下
public static void copyFile() { String path = "F:\\test.txt"; String path2 = "F:\\test2.txt"; try { FileInputStream fi = new FileInputStream(path); FileOutputStream fo = new FileOutputStream(path2); File f = new File(path); int l = (int) f.length(); byte[] b = new byte[l]; int len = 0; while((len=fi.read(b))!=-1) { fo.write(b,0,len); } fo.flush(); fo.close(); fi.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
综合使用之前读取的方式。
3.文件字符输入流、文件字符输出流
public static void testFileReader() { String path = "F:\\test.txt"; try { FileReader fr = new FileReader(path); //注意这里是char类型的数组了 char[] c = new char[20]; int len = 0; while((len=fr.read(c))!=-1) { System.out.println(new String(c, 0, len)); } fr.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void testFileWriter() { String path1 = "F:\\test2.txt"; try { FileWriter fw = new FileWriter(path1); String str = "这是我测试的输入"; //注意这里可以直接写入字符串 fw.write(str); fw.flush();//将内存中的数据写到文件中 fw.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
需要注意的是定义char数组时仍然是需要知道数据是有多少字符的,不然长度不够,显示不全或者写入不全。(这里暂时还未了解怎么处理)
4.使用字符流将一个文件复制到指定的文件夹下
public static void copyFile2() { String path = "F:\\test.txt"; String path2 = "F:\\test2.txt"; try { FileReader fr = new FileReader(path); FileWriter fw = new FileWriter(path2); char[] c = new char[30]; int len = 0; while((len=fr.read(c))!=-1) { fw.write(c,0,len); } fw.flush(); fw.close(); fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
二、带缓冲的流
为了提高数据的读写速度,java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组。
根据数据操作单位可以把缓冲流分为:BufferedInputStream/BufferedOutputStream和BufferedReader/BufferedWriter。
缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了些新方法。对于输出的缓冲流,写出的数据都会先在内存中缓存,使用flush()会将在内存中的数据立即写出。
1.缓冲字节输入流、缓冲字节输出流
package anno; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test4 { public static void main(String[] args) throws IOException { testBufferedInputStream(); testBufferedOutputStream(); copyFile(); } public static void testBufferedInputStream() throws IOException { FileInputStream fi = new FileInputStream("F:\\test.txt"); //把文件字节输入流放入到缓冲输入流中 BufferedInputStream bi = new BufferedInputStream(fi); byte[] b = new byte[35]; int len = 0; while((len=bi.read(b))!=-1) { System.out.println(new String(b, 0, len)); } bi.close(); fi.close(); } public static void testBufferedOutputStream() throws IOException { FileOutputStream fo = new FileOutputStream("F:\\test3.txt"); //把文件字节输入流放入到缓冲输入流中 BufferedOutputStream bo = new BufferedOutputStream(fo); String str = "这是我测试的内容"; bo.write(str.getBytes()); bo.flush(); bo.close(); fo.close(); } public static void copyFile() { String path = "F:\\test.txt"; String path2 = "F:\\test2.txt"; try { FileInputStream fi = new FileInputStream(path); BufferedInputStream bi = new BufferedInputStream(fi); FileOutputStream fo = new FileOutputStream(path2); BufferedOutputStream bo = new BufferedOutputStream(fo); File f = new File(path); int l = (int) f.length(); byte[] b = new byte[l]; int len = 0; while((len=bi.read(b))!=-1) { bo.write(b,0,len); } bo.flush(); bo.close(); fo.close(); bi.close(); fi.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.缓冲字符输入流、缓冲字符输出流
package anno; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Test3 { public static void main(String[] args) { testBufferedReader(); testBufferedWriter(); copyFile(); } public static void testBufferedReader() { String path = "F:\\test.txt"; try { FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr); char[] c = new char[17]; int len = 0; while((len=br.read(c))!=-1) { System.out.println(new String(c, 0, len)); } br.close(); fr.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void testBufferedWriter() { String path1 = "F:\\test2.txt"; try { FileWriter fw = new FileWriter(path1); BufferedWriter bw = new BufferedWriter(fw); String str = "这是我测试的输入"; bw.write(str);//将数据写到chars中 bw.flush();//将内存中的数据写到文件中 bw.close(); fw.close();//关闭 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void copyFile() { String path = "F:\\test.txt"; String path2 = "F:\\test2.txt"; try { FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr); FileWriter fw = new FileWriter(path2); BufferedWriter bw = new BufferedWriter(fw); char[] c = new char[30]; int len = 0; while((len=br.read(c))!=-1) { bw.write(c,0,len); } bw.flush(); bw.close(); fw.close(); br.close(); fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
三、转换流:用于字节流和字符流之间的转换
java Api提供了两个转换流:InputStreamReader和OutputSreamWriter。
当字节流中的数据都是字符时,转换成字符流操作更高效
package anno; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class Test5 { public static void main(String[] args) throws IOException { testInputStreamReader(); testOutputStreamWriter(); } public static void testInputStreamReader() throws IOException { FileInputStream fi = new FileInputStream("F:\\test.txt"); //字节流转换成字符流 //注意转换成的编码要和读取的文件一致 InputStreamReader ir = new InputStreamReader(fi,"utf-8"); char[] c = new char[17]; int len = 0; while((len=ir.read(c))!=-1) { System.out.println(new String(c, 0, len)); } ir.close(); fi.close(); } public static void testOutputStreamWriter() throws IOException { FileOutputStream fo = new FileOutputStream("F:\\test3.txt"); //转换字节输出流为字符输出流 OutputStreamWriter ow = new OutputStreamWriter(fo,"utf-8"); String str = "这是我测试的内容"; ow.write(str); ow.flush(); ow.close(); fo.close(); } public static void copyFile() { String path = "F:\\test.txt"; String path2 = "F:\\test2.txt"; try { FileInputStream fi = new FileInputStream(path); BufferedInputStream bi = new BufferedInputStream(fi); FileOutputStream fo = new FileOutputStream(path2); BufferedOutputStream bo = new BufferedOutputStream(fo); File f = new File(path); int l = (int) f.length(); byte[] b = new byte[l]; int len = 0; while((len=bi.read(b))!=-1) { bo.write(b,0,len); } bo.flush(); bo.close(); fo.close(); bi.close(); fi.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
四、标准输入输出流
package anno; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; public class Test6 { public static void main(String[] args) throws IOException { // testSystemIn(); testWriterToTxt(); } public static void testSystemIn() throws IOException { //创建一个获取键盘输入的输入流 InputStreamReader ir = new InputStreamReader(System.in); //将输入流放在缓冲中 BufferedReader br = new BufferedReader(ir); String str = ""; while((str = br.readLine())!=null) { System.out.println(str); } } //将控制台的输入写入到txt文件中 public static void testWriterToTxt() throws IOException { //创建一个获取键盘输入的输入流 InputStreamReader ir = new InputStreamReader(System.in); //将输入流放在缓冲中 BufferedReader br = new BufferedReader(ir); BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\test5.txt")); String line = ""; while((line = br.readLine())!=null) { if (line.equals("over")) { break; } bw.write(line); } bw.flush(); bw.close(); br.close(); ir.close(); } }
五、数据流
package anno; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Test7 { public static void main(String[] args) throws IOException { testDataOutputStream(); testDataInputStream(); } //用数据输出流写到文件中的基本类型数据是乱码,不能辨认出来,需要数据输入流读取 public static void testDataOutputStream() throws IOException { DataOutputStream ds = new DataOutputStream(new FileOutputStream("F:\\test6.txt")); ds.writeDouble(1.35d); ds.flush(); ds.close(); } public static void testDataInputStream() throws IOException { DataInputStream ds = new DataInputStream(new FileInputStream("F:\\test6.txt")); System.out.println(ds.readDouble()); ds.close(); } }
六、对象流
用于存储和读取对象的处理流,它的强大之处就是可以把java中对象写入到数据源中,也能把对象从数据源中还原出来。
序列化:用ObjectOutputStream类将一个对象下入io流中;
反序列化:用ObjectInputStream类从io流中恢复对Java对象;
package anno; import java.io.Serializable; public class Person implements Serializable{ //用来标识的UID private static final long serialVersionUID = 1L; String name; int age; }
package anno; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Test8 { public static void main(String[] args) throws IOException, ClassNotFoundException { // testSerializable(); testDeSerializable(); } //序列化 public static void testSerializable() throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("F:\\test7.txt")); Person p = new Person(); p.name = "tom"; p.age = 12; oos.writeObject(p); oos.flush(); oos.close(); } //反序列化 public static void testDeSerializable() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("F:\\test7.txt")); Person p = null; Object obj = null; obj = ois.readObject(); p = (Person) obj; System.out.println(p.name); System.out.println(p.age); ois.close(); } }
七、RandomAccessFile
支持随机访问的方式,程序可以直接跳转到文件的任意位置地方来进行读写。支持只访问文件的部分内容,可以向已存在的文件后追加内容。
RandomAccessFile对象包含一个记录指针,用以标记当前读写的位置。
RandomAccessFile类对象可以自由地移动和记录指针:
- long getFilePoint():获取文件记录指针的当前位置;
- void seek(long pos):将文件记录指针移动到指定位置;
package anno; import java.io.IOException; import java.io.RandomAccessFile; public class Test9 { public static void main(String[] args) throws IOException { // testRandomAccessFileRead(); testRandomAccessFileWrite(); } public static void testRandomAccessFileRead() throws IOException { //构造方法有两个参数,参数一为路径,参数二为访问方式 //r:只读 //rw:可写可读 //rwd:可写可读,同步内容跟新 //rws:可写可读,同步内容和元数据跟新; RandomAccessFile acf = new RandomAccessFile("F:\\test7.txt","r"); //设置文件起始的读取位置 acf.seek(5); byte[] b = new byte[35]; int len = 0; while((len=acf.read(b))!=-1) { System.out.println(new String(b, 0, len)); } acf.close(); } public static void testRandomAccessFileWrite() throws IOException { //构造方法有两个参数,参数一为路径,参数二为访问方式 //r:只读 //rw:可写可读 //rwd:可写可读,同步内容跟新 //rws:可写可读,同步内容和元数据跟新; RandomAccessFile acf = new RandomAccessFile("F:\\test7.txt","rw"); //设置文件起始的写入位置,0代表开头,acf.length代表文件末尾 acf.seek(acf.length()); acf.write("你好".getBytes()); acf.close(); } }
总结:
流适用于处理数据的。
处理数据时,一定要明确数据源,与数据目的地:数据源可以是文件,也可以是键盘;数据目的地可以是文件、显示器或其它设备。
流只是帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。
您可能感兴趣的文章:
加载全部内容