IO


输入流和输出流

Java中的IO流根据功能划分为:输入流和输出流。输入流:用于读取数据。输出流:用于写出数据。输入输出的参照方向是根据我们的程序的。

字节流和字符流

Java中的IO流根据处理的单位划分为:字节流和字符流。字节流:以字节为单位读写数据。字符流:以字符为单位读写数据。

高级流和低级流

Java中的IO流还分为:高级流和低级流。高级流:不能独立存在,必须基于另一个流工作。低级流:数据有明确的来源或者去向

字节流和字符流


字节流

InputStream:抽象类,是所有字节输入流的父类。

OutputStream:抽象类,是所有字节输出流的父类。

字符流

Reader与Writer 带有缓冲区。

Reader:抽象类,所有字符输入流的父类,不能实例化

Writer:抽象类,所有字符输出流的父类,不能实例化

字符流处理单位为字符:一次处理一个字符unicode。字符流本质上还是读写字节。

FISFOS


用于读写文件的流。FileInputStream:文件字节输入流,是低级流。FileOutputStream:文件字节输出流,是低级流。

FileOutputStream

构造器:

FileOutputStream(String name) 根据文件名创建用于写该文件的输出流。

FileOutputStream(File file)

FileOutputStream(File file, boolean append) append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处。

如果文件不存在,会自动创建该文件。

方法:

void write(int   d)写一个字节,写给定的int值的”低八位”

void write(byte[] d)将给定的字节数组中的所有字节一次性写出

void write(byte[] d, int start,int len)从下标start开始,写len个字节。

FileOutputStream

构造器:

FileOutputStream(File file)

FileOutputStream(String name)当前目录是相对于根目录下的

FileOutputStream(String name, boolean append)

方法:

int read() 读取1个字节,8位

int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入 b 中

int read(byte[] b, int off, int len)

从输入流中将最多 len 个字节的数据读入一个 byte 数组中。从off处开始放

long skip(long n) 从输入流中跳过并丢弃 n 个字节的数据。

public class TestFile {
public static void main(String[] args) throws Exception {
OutputStream out = null;
try{
out = new FileOutputStream("test.txt");
out.write(1);
out.write('A');
byte[] bytes = "大家好".getBytes("utf-8");
out.write(bytes.length);
out.write(bytes);
}
catch(Exception e){
}
finally{
if(out != null){
try{
out.close();
}
catch(IOException e){
}
}
}
}
}

public class TestFile {
public static void main(String[] args) throws Exception {
InputStream in = null;
try{
in = new FileInputStream("test.txt");
System.out.println(in.read());//
System.out.println((char)in.read());// 'A'
int len = in.read();
byte[] bytes = new byte[len];
in.read(bytes);
String str = new String(bytes, "utf-8");
System.out.println(str);
}
catch(Exception e){
}
finally{
if(in != null){
try{
in.close();
}
catch(IOException e){
}
}
}
}
}

复制文件

public class TestFile {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("E:\\代码整体规范.pptx");
FileOutputStream fos = new FileOutputStream("E:\\代码整体规范222.pptx");
byte[] buffer = new byte[1024 * 10];// 10k
int len = -1;
while((len = fis.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
fis.close();
fos.close();
}
}

BISBOS


BufferedInputStream:缓冲字节输入流

BufferedOutputStream:缓冲字节输出流

缓冲流的功能:内部维护一个缓冲区,用于减少读写次数,提高读写效率。

BufferedOutputStream

原理:BufferedOutputStream内部有一个缓冲区,大小8192k,每次调用write方法的时候,它首先把数据放入缓冲区中,等缓冲区存满后,调用方法out.write(buf,0,count)把缓冲区中的内容写出。这样提高的写的效率,不是一个字节一个字节的写。

构造器:

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out, int size) size:指定缓冲区大小

方法:

void flush() 刷新此缓冲的输出流。

void write(byte[] b, int off, int len)

void write(int b)

   BufferedInputStream

原理:

BufferedInputStream内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快,所以BufferedInputStream的效率很高!

构造器:

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in, int size) size指的是缓冲区大小

方法:

read()

int read(byte[] b, int off, int len)

复制文件

public class TestFile {
public static void main(String[] args) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.zip"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b"));
int d = -1;
// bis和bos内部都维护了一个缓冲数组,(8192)
while((d = bis.read()) != -1){// read方法一次性读取多个字节放入缓冲区中
bos.write(d);// 把读到的字节放入缓冲数组中,数组装满了,再一次性写出
}
bis.close();
bos.close();
}
}

flush方法

public class TestFile {
public static void main(String[] args) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
bos.write("大家好".getBytes("utf-8"));
// 没有真正写出,而是放入缓冲区中.等缓冲区满了才写出
bos.flush();// 把缓冲数组中的数据全部写出。
bos.close();// 先调用flush()方法后再关闭。所以最后一定要关闭,否则可能会丢数据
// 一般有缓冲区的flush方法有效,没有缓冲区的flush方法没有任何作用
}
}

DISDOS


方便读写基本数据类型,但是效率不高,和RandomaccessFile的功能相似。

DataInputStream:可以方便的读取基本类型数据

DataOutputStream:可以方便的写出基本类型数据

DataOutputStream

构造器:DataOutputStream(OutputStream out),传入低级流,如FileOutputStream

方法:

size()   返回即到目前为止写入此数据输出流的字节数。

void write(byte[] b, int off, int len)

void write(int b) 将指定字节(参数 b 的八个低位)写入基础输出流。

void writeBoolean(boolean v)

void writeChar(int v)

void writeDouble(double v)

void writeFloat(float v)

void writeInt(int v)

void writeLong(long v)

void writeShort(int v)

void writeUTF(String str)

   DataInputStream

构造器:

DataInputStream(InputStream in) ,传入低级流,如FileInputStream

方法:

int read(byte[] b)

int read(byte[] b, int off, int len)

boolean readBoolean()

char readChar()

double readDouble()

float readFloat()

int readInt()

long readLong()

short readShort()

String readUTF()

int skipBytes(int n)

DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
dos.writeInt(1000);
dos.writeLong(34l);
dos.writeDouble(2.34);
dos.writeUTF("你好");
dos.close();

DataInputStream dis=new DataInputStream(new FileInputStream("dos.txt"));
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
dis.close();

高级流的组合使用

我们既要可以方便的写出基本数据类型,又要写的效率高,那么我们可以联合使用DOS、BOS

FileOutputStream fos = new FileOutputStream("a.txt");
// 首先,为了提高些效率,包装为缓冲流。
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 为了方便的写出基本类型数据,包转为DOS
DataOutputStream dos = new DataOutputStream(bos);
// dos既可以方便的写出基本类型数据,又提高了效率
dos.writeInt(1234);
dos.close();

ISROSW


InputStreamReader: 字符输入流  OutputStreamWriter:字符输出流

OutputStreamWriter

构造器:

OutputStreamWriter(OutputStream out) ,使用默认字符编码,平台默认的编码 window默认是gbk,liunx默认是utf-8

OutputStreamWriter(OutputStream out, String charsetName) 使用指定字符编码

方法:

void  write(int c)               写入单个字符,即c的低16位

void  write(char[] cbuf)             一次性将给定的字符数组中的所有字符写出

void  write(char[] cbuf, int off, int len) 从start处开始连续将len字符写出

void  write(String str)

void  write(String str, int off, int len) 写入字符串的某一部分。

String getEncoding()            返回此流使用的字符编码的名称。

InputStreamReader

构造器:

InputStreamReader(InputStream in)

InputStreamReader(InputStream in, String charsetName)

方法:

String getEncoding()   返回此流使用的字符编码的名称。

int read()     读取单个字符。以int值形式返回,该int值”低16位”有效。如果是utf-8编码方案,会一个一个匹配,先读一个字符如果是英文字符,进行编码。不是英文字符则再读一个字符,中文字符占3个字符, 会一次性读取3个字符,把它按照utf-8解码成字符,再以unicode编码存在char中。

int read(char[] c)  一次最多尝试读取给定数组的length个字符,并存入数组返回值为实际读取到的字符

int read(char[] cbuf, int offset, int length)

OutputStreamWriter osw=new OutputStreamWriter(System.out);//写到控制台
osw.write(123);
osw.write(new char[]{'A','B'});
osw.write("大家好!");
System.out.println(osw.getEncoding());
osw.close();

InputStreamReader reader=new InputStreamReader(new FileInputStream("b.txt"));
int c=-1;
while((c=reader.read())!=-1){
char chs=(char)c;
System.out.print(chs);
}
reader.close();

从控制台读

InputStreamReader reader=new InputStreamReader(System.in);
char[] chs=new char[3];
reader.read(chs);//阻塞方法,如果控制台没有数据会等待控制台输入
System.out.println(Arrays.toString(chs));
reader.close();

复制”文本文件”

只能复制文本文件,不是什么文件都能复制的

InputStreamReader reader=new InputStreamReader(new FileInputStream("src"+File.separator+"demo"+File.separator+"Demo01.java"));
OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("E:\\a.java"));
char[] chs=new char[1024*10];
int len=-1;
while((len=reader.read(chs))!=-1){
writer.write(chs, 0, len);
}
reader.close();
writer.close();

BRBW


BufferedReader:缓冲字符输入流

BufferedWriter:缓冲字符输出流

可以实现按行读取。

BufferedWriter

构造器:

BufferedWriter(Writer out) 传入一个字符流

BufferedWriter(Writer out, int size)传入一个字符流,size指的是缓冲区大小

方法:

void flush()

void newLine() 写入一个行分隔符。

void write(int c) 写入单个字符。

void write(char[] chs)

void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。

void write(String str)

void write(String s, int off, int len) 写入字符串的某一部分。

BufferedReader

构造器:

BufferedReader(Reader in)

BufferedReader(Reader in, int sz)

方法:

int read() 读取单个字符。

int read(char[] chs)

int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。

String readLine() 读取一个文本行。

案例

BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8"));
writer.write("你好!");
writer.newLine();
writer.write("你好!");
writer.newLine();
writer.close();

BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
String str=null;
while((str=reader.readLine())!=null){
System.out.println(str);
}
reader.close();

或者

BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
char[] chs=new char[5];
int len=-1;
while((len=reader.read(chs))!=-1){
System.out.print(new String(chs));
}
reader.close();

复制文件

BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("src/demo/Demo01.java"),"gbk"));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\a.java"),"gbk"));
String line=null;
while((line=reader.readLine())!=null){
writer.write(line);
writer.newLine();
}
reader.close();
writer.close();

读取控制台中的数据,复制到文本文件中

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")));
String str=null;
while(true){
str=reader.readLine();
if(str!=null&&str.equals("bye")){
break;
}
writer.write(str);
writer.newLine();
}
reader.close();
writer.close();

FileWriterFileReader


可以直接读写文本文件的字符流。比较方便。但是使用FileWriter和FileReader就默认使用了当前系统默认的字符集进行读写。不能自己设置字符集,所以用的不是太多。

FileWriter extends OutputStreamWriter

构造器:

FileWriter(File file)

FileWriter(File file, boolean append)

FileWriter(String fileName)

FileWriter(String fileName, boolean append)

构造方法实现

public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}
//即new FileWriter(“a.txt”)完全相当于new OutputStreamWriter(new FileOutputStream(a.txt))

方法:全部继承于OutputStreamWriter。

FileReader extends InputStreamReader

构造器:

FileReader(File file)

FileReader(String fileName)

public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}
//即new FileReader(“a.txt”)完全相当于new InputStreamReader(new FileInputSteam(“a.txt”))

方法:全部继承于InputStreamReader

FileWriter writer=new FileWriter("a.txt");
writer.write("你好");
//变成缓冲字符流
BufferedWriter br=new BufferedWriter(writer);
br.write("%%%");
br.close();

FileReader reader=new FileReader("a.txt");
int c=-1;
while((c=reader.read())!=-1){
System.out.println((char)c);
}
reader.close();

PrintWriter


缓冲字符输出流。在写文件时,可以指定字符集,比较方便。

构造器:

PrintWriter(File file)

PrintWriter(File file, String charset)

PrintWriter(String fileName)

PrintWriter(String fileName, String charset)

PrintWriter(OutputStream out)

PrintWriter(OutputStream out, boolean autoFlush) 自动刷新

创建带有自动刷新的缓冲字符输出流,每当调用"pringln()"注意是带有ln方法。就会在写操作后自动调用flush()方法,即自动刷新

PrintWriter(Writer out)

PrintWriter(Writer out, boolean autoFlush)

//该构造器既能指定字符集也能指定自动刷新

方法:

void print();输出,不带换行符,和System.out.print()差不多

void println() 带换行符

void write(char[] buf)

void write(char[] buf, int off, int len)

void write(int c)

void write(String s)

void write(String s, int off, int len)

案例

PrintWriter pw=new PrintWriter("p.txt","utf-8");
pw.println(true);
pw.println(1234567);
pw.println("你好!");
//注意,写入文件中的是字符串,true,1234567,你好
pw.close();

Serializable接口


public interface Serializable类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。

序列化接口没有方法或字段,仅用于标识可序列化的语义。

transient关键字

transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象呗串行化的时候,transient型的便利的值不包括再串行化的表示中,然而非transient型的变量是被包括进去的。

Transient修饰的属性可以通过其它手段进行序列化,可以参考ArrayList源码,ArrayList中底层数组是用transient修饰,但是进行了序列化。因为重写了readObject和writeObject方法。

OOSOIS


将Object对象转换为byte序列,就是序列化,反之叫反序列化。

ObjectOutputStream:对象输出流

ObjectInputStream:对象输入流

ObjectOutputStream

构造器:ObjectOutputStream(OutputStream out)

方法:void writeObject(Object obj) 线程安全的方法

ObjectInputStream

构造器:ObjectInputStream(InputStream in)

方法:readObject()   线程安全的方法

public class Person implements Serializable {
private String name;
private int age;
private int sex;
private transient String info;
private List<String> otherInfo;
//...get/set方法 equals方法 hashcode方法
}

读写

public class Test {
public static void main(String[] args) throws Exception {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("a.txt"));
List<String> list = new ArrayList<String>();
list.add("一");
list.add("二");
list.add("三");
Person p = new Person("zhansgan", 22, 1, "男", list);
// 将p的name、age、sex、otherInfo值转换成二进制写入文件
// 比如name=zhangsan, 取’z’二进制为:1111010写入只有在写字符串时才有编码格式问题
out.writeObject(p);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("a.txt"));
Person p1 = (Person)in.readObject();
System.out.println(p1);// info值是null,没有被序列化
System.out.println(p1.equals(p));
in.close();
}
}

文件(2)--IO流的更多相关文章

  1. 文件和IO流

    摘要:本文主要介绍了Java的文件处理以及常用的IO流操作. 文件操作 概念 File是数据源(保存数据的地方)的一种,可以表示一个文件,也可以表示一个文件目录. File类只能对文件和文件夹进行创建 ...

  2. 2018.4.13 用java配置/生成Xml文件 结合IO流知识点

    自己创建本地文件Hello.txt 里面有数据 小明/23/增城/广东 小花/12/浦东/上海 StudentManager.java package com.lanqiao.dmeo7; impor ...

  3. 【java学习笔记】文件读写(IO流)

    1.字节流 FileInputStream.FileOutputStream ①FileInputStream import java.io.FileInputStream; public class ...

  4. 文件操作IO流

    fopen 打开文件或者生成文件 getc 向文件中读取一个字符 putc 向文件中写入一个字符 fgets 向文件中读取字符串 参数可以设置获取多少个字符串 fputs 向文件中写入字符串 不自动添 ...

  5. java IO流文件的读写具体实例(转载)

    引言: 关于java IO流的操作是非常常见的,基本上每个项目都会用到,每次遇到都是去网上找一找就行了,屡试不爽.上次突然一个同事问了我java文件的读取,我一下子就懵了第一反应就是去网上找,虽然也能 ...

  6. io流(io流的引入与文件字节流)

    io流的引入与文件字节流 io流:就是一根吸管,插入后,可以操作目标文件 io流的分类: 按方向:输入,输出 按大小:字节,字符 按处理方式: 处理流:"管套着管" --- 流结合 ...

  7. Java学习 · 初识 IO流

    IO流   1. 原理与概念 a)     流 i.           流动,流向 ii.           从一端移动到另一端 源头到目的地 iii.           抽象.动态概念,是一连 ...

  8. JAVA中IO流详解

    IO流:数据传输是需要通道的,而IO流就是数据传输的通道. IO流可以形象的比喻为运送货物的传输带. IO流的分类: ①根据操作的数据类型的不同可以分为 :字节流与字符流. ②根据数据的流向分为:输入 ...

  9. Java:IO流与文件基础

    Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...

随机推荐

  1. 8782:乘积最大(划分dp)

    8782:乘积最大   同洛谷 P1018 乘积最大 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我 ...

  2. WebBench----简洁优美的网站压力测试工具

    [root@c webbench]# webbench -c 10 -t 20 http://www.baidu.com/Webbench - Simple Web Benchmark 1.5Copy ...

  3. linux下EOF写法梳理 自动新建分区并挂载的脚本

    linux下EOF写法梳理 - 散尽浮华 - 博客园 https://www.cnblogs.com/kevingrace/p/6257490.html 在平时的运维工作中,我们经常会碰到这样一个场景 ...

  4. caffe使用(2)

    总体流程 https://blog.csdn.net/hjimce/article/details/48933813 https://zhuanlan.zhihu.com/p/24087905 1.编 ...

  5. 解决ajax无法给js全局变量赋值的问题

    解决ajax无法给js全局变量赋值的问题 http://blog.csdn.net/qq_26222859/article/details/51543433 在ajax中是无法给js中的全局变量赋值的 ...

  6. oracle入门(3)——oracle服务解释

    [本文介绍] oracle不像mysql,安装后之后一个服务,如果mysql连接不上,打开其服务就行.oracle是有多个服务,哪些服务要开,哪些服务没必要开,对新手来说未必不是一个难点.下面对ora ...

  7. 007-Centos 7.x 安装 Mysql 5.7.13

    1. 下载mysql的repo源 CentOS 7.2的yum源中默认没有mysql,要先下载mysql的repo源 wget http://repo.mysql.com/mysql57-commun ...

  8. Angular4中常用管道(转载)

    Angular4中常用管道 通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化,下面说一些常用的管道. 一.大小写转换管道 uppercase将字符串转换为大写 low ...

  9. tensorflow 的rnn的示例 ptb_word_lm.py 的完整代码

    其训练数据源在我的空间里,名字为:tensorflow的ptb-word-lm示例的训练数据源.tgz 讲解参见另一篇文章:  http://www.cnblogs.com/welhzh/p/6739 ...

  10. tarball源码安装

    软件最原始的安装方法 用tarball来安装升级make命令执行make ,会在当前路径下搜索makefile这个文本文件,这个文件中记录了源码如何编译的详细信息.软件开发商通常会写一个检测程序,检测 ...