按操作单位的不同分为:字节流(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();
}
}

总结:

流适用于处理数据的。

处理数据时,一定要明确数据源,与数据目的地:数据源可以是文件,也可以是键盘;数据目的地可以是文件、显示器或其它设备。

流只是帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

最新文章

  1. AlertDialog的六种创建方式
  2. JS弹出浮层
  3. JAVA源码走读(一) HashMap与ArrayList
  4. 国内首个微信小程序开发者社区www.mntuku.cn
  5. hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)
  6. CSS中vw和vh单位的使用
  7. php获取汉字的拼音 拼音首字母
  8. Allow windows service to "Interact with desktop"
  9. iOS 中关闭键盘方法
  10. StoreKit framework
  11. POJ 1681 Painter's Problem (高斯消元 枚举自由变元求最小的步数)
  12. java常见内存溢出(OOM)
  13. Is Fibo
  14. linux删除、移动、拷贝时,加-f仍然会提示的解决办法
  15. 聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析
  16. 【数据可视化-Echarts】Echart基础
  17. 介绍一个axios调试好用的工具:axios-mock-adapter
  18. JustOj 2009: P1016 (dp)
  19. JVM垃圾回收算法及分代垃圾收集器
  20. Spring Boot 揭秘与实战(五) 服务器篇 - 其他内嵌服务器 发表于 2017-01-03 | Spring框架 | Spri

热门文章

  1. AutoCAD二次开发(2020版)--4,使用ARX向导创建编程模板(框架)--
  2. php踩过的那些坑(5)浮点数计算
  3. Scrapy爬虫及案例剖析
  4. libnl的移植
  5. 转:OAuth2 深入介绍
  6. 阿里巴巴 Service Mesh 落地的架构与挑战
  7. 上手spring boot项目(二)之spring boot整合shiro安全框架
  8. 简单理解http协议的特性
  9. 爬虫学习(二)--爬取360应用市场app信息
  10. Pandas学习(三)——NBA球员薪资分析