Java IO学习笔记
Java流的分类,一般可按以下方式分:
- 按方向分,分为输入流,输出流。
- 按类型分,分为字节流和字符流。
2.1字节流是通过字节来读取数据
2.2字符流是通过字符来读取数据 - 按操作方式分,分为节点流和过滤流。
3.1 可以直接创建的流称为节点流,比如输入流,输出流
3.2 过滤流可以装饰节点流,让流的功能变得更加强大,过滤流采用装饰者模式,对输入流进行包装。比如说BufferedInputStream,BufferedOutputStream,DataInputStream,DataOutputStream都是过滤流。 - 转换流。
废话不多说,看代码:
使用字节流读取文件内容:
public void test1(){
File file = new File("F:\\hello.txt");
FileInputStream fis = null;
try {
//创建一个文件输入流
fis = new FileInputStream(file);
//创建一个字节数组用来存储读取的信息
byte[] buf = new byte[1024];
//len表示读取的长度
int len = 0;
//只要len大于-1说明读取到元素,可对元素直接进行操作
while((len=fis.read(buf))>-1){
//通过控制台输出程序,需要指明输出的长度
System.out.write(buf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (fis!=null) {
//操作完成之后关闭流
fis.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如何通过操作字节流来实现简单的文件拷贝呢?使用未经包装的输入输出流来拷贝文件,看代码:
public void test2(){
long startTime = new Date().getTime();
File file = new File("F:\\mysql-installer-community-5.6.22.0.msi");
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream("F:\\1.msi");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
fos.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fis!=null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fos!=null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = new Date().getTime();
//查看效率
System.out.println((endTime-startTime)/1000);
}
最后的输出结果为2,也就是说拷贝一个接近300M的文件需要两秒钟。
再看看经过BufferedInputStream和BufferedOutputStream包装后的相同文件的拷贝,代码如下:
public void test3(){
long startTime = new Date().getTime();
File file = new File("F:\\mysql-installer-community-5.6.22.0.msi");
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(file);
//将fis包装起来
bis = new BufferedInputStream(fis);
//将输出流包装
bos = new BufferedOutputStream(new FileOutputStream("F:\\2.msi"));
byte[] buf = new byte[1024];
int len = 0;
while((len=bis.read(buf))!=-1){
bos.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流之后会自动flush
try {
if(bis!=null) bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bos!=null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = new Date().getTime();
System.out.println((endTime-startTime)/1000);
}
这里的输出为0,也就是说相同的文件拷贝,包装后的流效率会大大提高,原先需要两秒才能完成的拷贝,现在1秒都不到。
再看DataInputStream和DataOutputStream,这两个依然是将InputStream流包装,包装完成之后可以用它写基本类型数据以及字符型数据。
public void test4(){
FileOutputStream fos = null;
DataOutputStream dos = null;
DataInputStream dis = null;
try {
fos = new FileOutputStream("F:\\2.txt");
dos = new DataOutputStream(fos);
/**
* 每写一个Int类型数据,相当于写入四个字节数据,占四个字节,long是八个字节
* 依次类推
*/
dos.writeInt(1111);
dos.writeInt(2222);
dos.writeInt(3333);
dis = new DataInputStream(new FileInputStream("F:\\2.txt"));
/**
* 每执行一次readInt(),相当于读取四个字节数据,读取其他数据依次类推
*/
System.out.println(dis.readInt());
System.out.println(dis.readInt());
System.out.println(dis.readInt());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(dos!=null) dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(dis!=null) dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
再看看包装后的字符流输入与输出:
public void test5(){
BufferedReader br = null;
PrintWriter out = null;
try {
br = new BufferedReader(new FileReader("F:\\hello.txt"));
out = new PrintWriter(new BufferedWriter(new FileWriter("F:\\11.txt")));
String str = null;
while((str=br.readLine())!= null){
System.out.println(str);
out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(br!=null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
if(out!=null) out.close();
}
}
字节流和字符流之间的转换,可以使用
字符流 =InputStreamReader(字节流)
把从控制台输入的文本内容转存到文本当中:
public void test6() {
BufferedReader br = null;
PrintWriter out = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
out = new PrintWriter(new BufferedWriter(new FileWriter(
"F:\\222.txt")));
String str = null;
while ((str = br.readLine()) != null) {
if (str.trim().equals("exit")) {
break;
}
System.out.println(str);
out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (out != null)
out.close();
}
}
把一个对象写入到文件中:
public void writeObject(){
User user = new User("zhangsan","123");
user.setMoney(200);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("F:\\object.dat"));
oos.writeObject(user);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(oos!=null) oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
User.java
import java.io.Serializable;
public class User implements Serializable{
private String username;
private String password;
//添加了transient属性的字段不会被存储
private transient int money;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
从文件中读取一个对象:
public void readObject(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("F:\\object.dat"));
User u = (User) ois.readObject();
System.out.println(u.getUsername()+","+u.getPassword()+","+u.getMoney());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
输出结果是:
由于给money字段添加了transient属性,所以money字段并不会被存储,当然也就读取不到。如果在User.java中删除transient,那么输出结果就是:
这个时候money就可被顺利的读取出来。
Java IO学习笔记的更多相关文章
- Java IO学习笔记:概念与原理
Java IO学习笔记:概念与原理 一.概念 Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...
- Java IO学习笔记总结
Java IO学习笔记总结 前言 前面的八篇文章详细的讲述了Java IO的操作方法,文章列表如下 基本的文件操作 字符流和字节流的操作 InputStreamReader和OutputStreamW ...
- Java IO学习笔记三
Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
- Java IO学习笔记一
Java IO学习笔记一 File File是文件和目录路径名的抽象表示形式,总的来说就是java创建删除文件目录的一个类库,但是作用不仅仅于此,详细见官方文档 构造函数 File(File pare ...
- Java IO学习笔记一:为什么带Buffer的比不带Buffer的快
作者:Grey 原文地址:Java IO学习笔记一:为什么带Buffer的比不带Buffer的快 Java中为什么BufferedReader,BufferedWriter要比FileReader 和 ...
- Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer
作者:Grey 原文地址:Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer ByteBuffer.allocate()与ByteBuffer.allocateD ...
- Java IO学习笔记三:MMAP与RandomAccessFile
作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...
- Java IO学习笔记四:Socket基础
作者:Grey 原文地址:Java IO学习笔记四:Socket基础 准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为: io1实例:192.168.205.138 io ...
- Java IO学习笔记六:NIO到多路复用
作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...
随机推荐
- 《深入理解linux内核》第三章 进程
进程的七种状态 在内核源码的 include/linux/sched.h文件中: task_struct的status可表示 #define TASK_RUNNING 0 #define TASK_I ...
- 手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类
简介 GestureDetector识别手势. GestureDetector.OnGestureListener是识别手势后的回调接口.GestureDetector.SimpleOnGesture ...
- 用if else 判断是不是7的倍数等
static void Main(string[] args) { while (true) { int b; ...
- bzoj1797
其实我觉得这种题目风格很像今天省选第三轮D1T1 都是在一个算法模型上去探索规律: 首先我们要做一遍最大流毫无疑问 第一问看起来很好想,只要是满流边就可以了? 错,反例不难找到 如:1--->2 ...
- 解决eclipse闪退的办法
Eclipse Java EE 便出现打开闪退的现象. 修改eclipse.ini无效,参照了网上许多方法也不行. 最后发现了一个蛋疼的方法: 1.打开eclipse的workspace目录 2.删除 ...
- [转]NHibernate之旅(11):探索多对多关系及其关联查询
本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...
- [Stephen]Export from Excel to ALM
1.根据当前安装的ALM版本和Excel版本到https://hpln.hp.com/page/alm-excel-addin-page中对应的插件进行下载安装,安装时Excel需要关闭.安装成功后, ...
- Cocos2d-x v3.3 lua绑定c++类方法总结
网上有很多cocos2d-x lua绑定c++类的接口教程,这篇文章也是总结他们的经验. 其中重点参考了 http://cn.cocos2d-x.org/tutorial/show?id=1295, ...
- vijosP1359 Superprime
vijosP1359 Superprime 链接:https://vijos.org/p/1359 [思路] 搜索+数学. 很明显的搜索,依次确定每一个数,用参数sum记录dfs即可. 本题的关键在于 ...
- Azure VM对远程桌面登录的支持-示例
我们在开发Windows Azure的应用程序,虽然在大部分的情况下都可以使用Azure Emulator模拟器来模拟在云端计算节点(Azure VM)的执行结果,但是并不能100%模拟真正在Azur ...