文件(2)--IO流
IO流
输入流和输出流
Java中的IO流根据功能划分为:输入流和输出流。输入流:用于读取数据。输出流:用于写出数据。输入输出的参照方向是根据我们的程序的。
字节流和字符流
Java中的IO流根据处理的单位划分为:字节流和字符流。字节流:以字节为单位读写数据。字符流:以字符为单位读写数据。
高级流和低级流
Java中的IO流还分为:高级流和低级流。高级流:不能独立存在,必须基于另一个流工作。低级流:数据有明确的来源或者去向
字节流和字符流
字节流
InputStream:抽象类,是所有字节输入流的父类。
OutputStream:抽象类,是所有字节输出流的父类。
字符流
Reader与Writer 带有缓冲区。
Reader:抽象类,所有字符输入流的父类,不能实例化
Writer:抽象类,所有字符输出流的父类,不能实例化
字符流处理单位为字符:一次处理一个字符unicode。字符流本质上还是读写字节。
FIS和FOS
用于读写文件的流。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();
}
}
BIS和BOS
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方法没有任何作用
}
}
DIS和DOS
方便读写基本数据类型,但是效率不高,和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();
ISR和OSW
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();
BR和BW
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();
FileWriter和FileReader
可以直接读写文本文件的字符流。比较方便。但是使用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方法。
OOS和OIS
将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流的更多相关文章
- 文件和IO流
摘要:本文主要介绍了Java的文件处理以及常用的IO流操作. 文件操作 概念 File是数据源(保存数据的地方)的一种,可以表示一个文件,也可以表示一个文件目录. File类只能对文件和文件夹进行创建 ...
- 2018.4.13 用java配置/生成Xml文件 结合IO流知识点
自己创建本地文件Hello.txt 里面有数据 小明/23/增城/广东 小花/12/浦东/上海 StudentManager.java package com.lanqiao.dmeo7; impor ...
- 【java学习笔记】文件读写(IO流)
1.字节流 FileInputStream.FileOutputStream ①FileInputStream import java.io.FileInputStream; public class ...
- 文件操作IO流
fopen 打开文件或者生成文件 getc 向文件中读取一个字符 putc 向文件中写入一个字符 fgets 向文件中读取字符串 参数可以设置获取多少个字符串 fputs 向文件中写入字符串 不自动添 ...
- java IO流文件的读写具体实例(转载)
引言: 关于java IO流的操作是非常常见的,基本上每个项目都会用到,每次遇到都是去网上找一找就行了,屡试不爽.上次突然一个同事问了我java文件的读取,我一下子就懵了第一反应就是去网上找,虽然也能 ...
- io流(io流的引入与文件字节流)
io流的引入与文件字节流 io流:就是一根吸管,插入后,可以操作目标文件 io流的分类: 按方向:输入,输出 按大小:字节,字符 按处理方式: 处理流:"管套着管" --- 流结合 ...
- Java学习 · 初识 IO流
IO流 1. 原理与概念 a) 流 i. 流动,流向 ii. 从一端移动到另一端 源头到目的地 iii. 抽象.动态概念,是一连 ...
- JAVA中IO流详解
IO流:数据传输是需要通道的,而IO流就是数据传输的通道. IO流可以形象的比喻为运送货物的传输带. IO流的分类: ①根据操作的数据类型的不同可以分为 :字节流与字符流. ②根据数据的流向分为:输入 ...
- Java:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
随机推荐
- 8782:乘积最大(划分dp)
8782:乘积最大 同洛谷 P1018 乘积最大 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我 ...
- WebBench----简洁优美的网站压力测试工具
[root@c webbench]# webbench -c 10 -t 20 http://www.baidu.com/Webbench - Simple Web Benchmark 1.5Copy ...
- linux下EOF写法梳理 自动新建分区并挂载的脚本
linux下EOF写法梳理 - 散尽浮华 - 博客园 https://www.cnblogs.com/kevingrace/p/6257490.html 在平时的运维工作中,我们经常会碰到这样一个场景 ...
- caffe使用(2)
总体流程 https://blog.csdn.net/hjimce/article/details/48933813 https://zhuanlan.zhihu.com/p/24087905 1.编 ...
- 解决ajax无法给js全局变量赋值的问题
解决ajax无法给js全局变量赋值的问题 http://blog.csdn.net/qq_26222859/article/details/51543433 在ajax中是无法给js中的全局变量赋值的 ...
- oracle入门(3)——oracle服务解释
[本文介绍] oracle不像mysql,安装后之后一个服务,如果mysql连接不上,打开其服务就行.oracle是有多个服务,哪些服务要开,哪些服务没必要开,对新手来说未必不是一个难点.下面对ora ...
- 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 ...
- Angular4中常用管道(转载)
Angular4中常用管道 通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化,下面说一些常用的管道. 一.大小写转换管道 uppercase将字符串转换为大写 low ...
- tensorflow 的rnn的示例 ptb_word_lm.py 的完整代码
其训练数据源在我的空间里,名字为:tensorflow的ptb-word-lm示例的训练数据源.tgz 讲解参见另一篇文章: http://www.cnblogs.com/welhzh/p/6739 ...
- tarball源码安装
软件最原始的安装方法 用tarball来安装升级make命令执行make ,会在当前路径下搜索makefile这个文本文件,这个文件中记录了源码如何编译的详细信息.软件开发商通常会写一个检测程序,检测 ...