凡是与输入、输出相关的类、接口都定义在java.io包下

java.io.File类

1、File是一个类,可以有构造器创建其对象。此对象对应着一个文件或者一个目录。

2、File中的类,仅涉及到如何查找、创建、删除、重命名文件(.txt .jpg .java)或者目录(io\\io1)。如果涉及到文件里的内容的,File是无能为力的,只能用io流。

3、File类的对象常作为io流的具体类的构造器的形参。

4、mkdir和mkdirs:都是创建文件目录,但是mkdirs在没有上层目录的时候把上层所有缺失的目录都创建了,而mkdir则不行。

 //绝对路径(文件)
File file1 = new File("d:\\io\\hello.txt");
//相对路径(文件)
File file2 = new File("hello.txt");
//绝对路径(目录)
File file3 = new File("d:\\io\\io1");

 FileInputStream和FileOutputStream(字节流)

1、FileInputStream:从硬盘中读取一个文件到程序的内存中。

 //①先声明一个file类,如果"hello.txt"文件不存在,则会抛出FileNotFoundException异常
File file = new File("hello.txt");
//②创建一个FileInputStream类的对象
FileInputStream fis = new FileInputStream(file);
//③调用FileInputStream的方法,实现file文件的读取
int b = fis.read(); //read():读取下一个字节,执行到结尾返回-1
while(b!=-1){
  System.out.print((char)b);
fis.read();
}
//④关系相应的类,需要显示的关闭资源
fis.close();

上面再读取文件时候是一个字节一个字节的读取,这是不现实的,现实中我们肯定要一批一批的读取。
这时我们就要用到read的重载方法read(byte[])
刚才的b的就变成了每次读入到byte中字节的长度,刚才③中的代码改成如下代码:

 byte[] b = new byte[5]; //读取到的数据要写入的数据
int len; // 每次读入到byte中的字节的长度
while((len = fis.read(b)) = -1){
  for(int i = 0;i < len ;i++){
    system.out.print((char)b[i]);
  }
}

输出结果:abcdefg

如果把上面代码len修改成b.length,结果呢 :
输出结果:abcdefgcde

为什么呢?当第一次调用fis.read(b)的时候,b数组的5个元素就变成了b[0]= a, b[1] = b,b[2] = c, b[3] = d,b[4] = e,当第二次调用read的时候,b[0] = f,b[1] = g,但是后面没值了所以没变化了。

2、FileOutputStream:从内存中读取一个文件存储到磁盘中。

 // ①先声明一个file类,表明要写入的文件位置,输出的文件可以不存在,如果不存在则会自动创建
File file = new File("hello1.txt");
//②创建一个FileOutputStream类的对象
FileOutputStream fos = new FileOutputStream(file);
//③写入的操作
fos.write(new String("i love my family").getBytes());
//④关闭输出流
fos.close();

FileReader 和 FileWriter(字符流)
FileInputStream和FileOutputStream上面两个会了,这两个基本都一样的写法
把byte[]的b换成char[]就行了(字节换字符),其他的什么都不变

优点:可以读取到中文
缺点:只能处理文本文件,不能处理图片、视频等文件

BufferedInputStream和BufferedOutputStream
两个字节缓冲流(默认缓冲区大小是8M),可以提升读取文件速度
BUfferedOutputStream write完之后记着要flush 刷新一下

复制文件代码:

 public static void main(String[] args) {  

         long time = System.currentTimeMillis();  

         File source=new File("E:\\test\\a.txt");
File target=new File("E:\\copy");
FileInputStream fis=null;
FileOutputStream fos=null;
BufferedInputStream bis=null;
BufferedOutputStream bos=null; byte[] ch=new byte[1024];
int len=0; try {
//创建流对象
fis=new FileInputStream(source);
//创建缓冲流
bis=new BufferedInputStream(fis);
if(!target.exists()){
target.mkdirs();
}
fos=new FileOutputStream(new File(target,source.getName()));
bos=new BufferedOutputStream(fos);
while((len=bis.read(ch))!=-1){
bos.write(ch,0,len);
}
//刷新缓冲区
bos.flush(); } catch (IOException e) {
e.printStackTrace();
}finally{
StreamUtils.closeInput(fis);
StreamUtils.closeInput(bis); StreamUtils.closeOutput(fos);
StreamUtils.closeOutput(bos);
} int costTime = (int) (System.currentTimeMillis() - time);
System.out.println("使用BIS和BOS的时间为:" + costTime + "ms"); }

BufferedReader和BufferedWriter
两个字符缓冲流,可以提升文件读取速度(纯文本文件)

BufferedReader和BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。

word文件只能用字节流打开

例子:使用字符处理流实现文件复制

import java.io.*;
class IODemo
{
public static void main(String[] args)
{
try
{
//使用BufferedReader和BufferedWriter进行文件复制(操作的是字符,以行为单位读入字符)
FileReader fr=new FileReader("a.txt");
BufferedReader br=new BufferedReader(fr);
FileWriter fw=new FileWriter("d.txt");
BufferedWriter bw=new BufferedWriter(fw); String s=br.readLine();
while(null!=s)
{
bw.write(s);
//由于BufferedReader的rendLIne()是不读入换行符的,所以写入换行时须用newLine()方法
bw.newLine();
//read=fis.read(b);
s=br.readLine();
} br.close();
bw.close();
}
catch (IOException e)
{
e.printStackTrace();
} }
}

InputStreamReader和OutputStreamWriter 转换流
编码:字符串---》字节数组
解码:字节数组----》字符串

 public static void main(String[] args) throws IOException {
BufferedReader br = null;
BufferedWriter bw = null;
try{
//解码
File file = new File("dbcp.txt");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"GBK");
br = new BufferedReader(isr);
//编码
File file1 = new File("dbcp1.txt");
FileOutputStream fos = new FileOutputStream(file1);
OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
bw = new BufferedWriter(osw);
String str;
while ((str=br.readLine())!=null){
bw.write(str);
bw.newLine();
bw.flush();
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
bw.close();
br.close();
}
}

DataInputStream和DataOutputSteam 数据流
为了方便的操作java语言的基本数据类、String型、字节数组的数据,可以使用数据流

ObjectInputStream和ObjectOutputstream 对象流
用于存储和读取对象的处理流,它可以把对象写入到数据源中,也能把对象从数据源中还原回来。其实就是序列化和反序列化。

序列化:将内存中的java对象转换成二进制流,把这种二进制流永久的保存在磁盘上或者通过网络将这种二级制流传输到另一个网络节点。
反序列化:当其他程序获取了这种二进制流,恢复成原来的java对象。

① ObjectInputStream与ObjectOutputStream类所读写的对象必须实现Serializable接口,对象中transient和static类型成员变量不会被序列化

 import java.io.*;
public class serializtion { public static void main(String[] args)throws IOException{
  Student s1=new Student("张三", 1, 15, "化学");
  Student s2=new Student("李四", 2, 19, "生物");   FileOutputStream fout=new FileOutputStream("student.txt");
  ObjectOutputStream out=new ObjectOutputStream(fout);
  out.writeObject(s1);
  out.writeObject(s2);
  out.close();
  FileInputStream fin=new FileInputStream("student.txt");
  ObjectInputStream in=new ObjectInputStream(fin);
  try {
    s1=(Student) in.readObject();
    s2=(Student) in.readObject();
  } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  in.close();
  System.out.print("name:"+s1.name);
  System.out.print(" id:"+s1.id);
  System.out.print(" age:"+s1.age);
  System.out.println(" department:"+s1.department);
  System.out.print("name:"+s2.name);
  System.out.print(" id:"+s2.id);
  System.out.print(" age:"+s2.age);
  System.out.println(" department:"+s2.department);
}
}
import java.io.*;
public class Student implements Serializable {
  String name;
  int id ;
  int age;
  String department;
  public Student(String name, int id, int age, String department) {
  this.age = age;
  this.department = department;
  this.id = id;
  this.name = name;
}
}

RandomAccessFile 随机存取文件流
√ 既可以充当一个输入流,又充当一个输出流
√ 支持从文件的开头读取、写入。若文件不存在则创建,否则覆盖
√ 支持任意的位置的“插入”

跟着刚哥梳理java知识点——IO(十五)的更多相关文章

  1. 跟着刚哥梳理java知识点——运算符(五)

    运算符:是一种特殊的符号,用以表示数据的运算.赋值和比较. 1.算数运算符(+.-.*./.%.++.--) a)除: int i = 12; double d1 = i / 5; //2.0 dou ...

  2. 跟着刚哥梳理java知识点——多线程(十六)

    创建多线程第一种方式:① 继承:继承Thread.② 重写:重写Thread类的run()方法③ 创建:创建一个子类的对象④ 调用:调用线程的start()方法,启动此线程,调用run()方法 cla ...

  3. 跟着刚哥梳理java知识点——集合(十二)

    Java集合分为Collection和Map两种体系 一.Collection接口: Collections接口为我们提供了以下方法: size():返回集合中元素的个数 add(Object obj ...

  4. 跟着刚哥梳理java知识点——枚举和注解(十四)

    enum Season{ SPRING("spring","春暖花开"), SUMMER("summer","夏日炎炎" ...

  5. 跟着刚哥梳理java知识点——包装类(十)

    Java为8种基本数据类型都提供了对应的包装器类型 装箱和拆箱: public class Main { public static void main(String[] args) { Intege ...

  6. 跟着刚哥梳理java知识点——深入理解String类(九)

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...

  7. 跟着刚哥梳理java知识点——面向对象(八)

    面向对象的核心概念:类和对象. 类:对一类事物描述,是抽象的.概念上的定义. 对象:实际存在的该类事物的每个个体,因而也成为实例(Instance). Java类及类的成员:属性(成员变量Field) ...

  8. 跟着刚哥梳理java知识点——泛型(十三)

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: public class GenericTest { public static void main(String[] a ...

  9. 跟着刚哥梳理java知识点——变量之间的类型转换(四)

    变量之间的类型转换主要包括自动类型转换和强制类型转换. 1.自动类型转换:当容量小的数据类型与容量大的数据类型做运算时,容量小的会自动的转换成容量大的类型. [知识点]: a)char,byte,sh ...

随机推荐

  1. 关于select count

    关于select count,之前有一些不清楚的地方,看到阿里巴巴的Java编程规范,sql规约的第一条就是关于select count的 需要明确以下两点: 1.select count(常量)和s ...

  2. SQL SERVER 事务日志 解析

    1 基本介绍 每个数据库都具有事务日志,用于记录所有事物以及每个事物对数据库所作的操作. 日志的记录形式需要根据数据库的恢复模式来确定,数据库恢复模式有三种: 完整模式,完全记录事物日志,需要定期进行 ...

  3. python之数据库(mysql)操作

    前言: 最近开始学django了,学了下web框架,顿时感觉又会了好多知识.happy~~ 这篇博客整理写下数据库基本操作,内容挺少.明天写SQLAlchemy. 一.数据库基本操作 1. 想允许在数 ...

  4. Caffe学习系列(一)Ubuntu16.04下搭建编译Caffe环境,并运行MNIST示例(仅CPU)

    前言: 正文: 1.安装必要依赖包: sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev l ...

  5. LeetCode 笔记总结

    前言 之前把一些LeetCode题目的思路写在了本子上,现在把这些全都放到博客上,以后翻阅比较方便. 题目 99.Recover Binary Search Tree 题意 Two elements ...

  6. Spring 3.0 Aop 入门

    关于Aop的原理,动态代理,反射,之类的底层java技术网上搜一堆一堆的..我就不多说了,主要说在spring上使用aop的方法. 首先不得不说一下的就是,spring aop的支持需要外部依赖包: ...

  7. (七)javascript中的数组

    一. 一维数组 1.1 声明数组 var 数组名=new Array(数组大小); 1.2  添加元素 <script> var a=new Array(3); a[0]="张三 ...

  8. Gradle之恋-命令行详解

    虽然很多童鞋都必须要用IDE,但有些命令是IDE很难表现出来的,还是命令行返璞归真.本文就带你来剖析Gradle的命令行. 本文不包括试验性(incubating)的选项,如--configure-o ...

  9. 《jQuery实战(第二版)》读书笔记

    第一部分 jQuery核心 1.jQuery基础 第一章总结了jquery的大致功能,基本原理,使用方式. point: (1).引入:<script type="text/javas ...

  10. 不可重入定时器Newlife.TimerX

    在.net常用的定时器类有下面三种,使用定时器时需要设定参数,如间断时间.定时器计溢出后的回调函数.延时.开始等,定时器的的主要方法有开始.终止等,不同的定时器实现上述的方法会有一些差异,本文会针对具 ...