字节流
基本用法
package com.company.io.byteio;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 读取文件:按字节一个一个读取,效率低下
* FileInputStream 用于读取诸如图像数据之类的原始字节流。
* 1、建立联系: new File()
* 2、选择流: InputStream +FileInputStream
* 3、操作 读取: read()每次读取一个字节
* read(字节数组)按照字节批量读取,从此输入流中将最多 b.length个字节的数据读入一个 byte数组中
* 4、释放资源: close
* 字节输出流类似
*/
public class Demo1 {
public static void main(String[] args) {
File file=new File("c:/test.txt");
File pic=new File("c:/5.jpg");
InputStream is=null;
OutputStream os=null;
copyTxt(is,os,file);
copyPic(is,os,pic);
}
//txt文本的复制
public static void copyTxt(InputStream is,OutputStream os,File file){
try {
is=new FileInputStream(file);
//true表示数据追加在已有数据后,默认false,即清空后再写入
os=new FileOutputStream("c:/copy.txt",true);
byte[] buf=new byte[1024];
int length;
while((length=is.read(buf, 0, buf.length))!=-1){
System.out.println(new String(buf,0,length));
os.write(buf);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(is!=null){
is.close();
}
if(os!=null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//图片文件的复制
public static void copyPic(InputStream is,OutputStream os,File file){
try {
//缓冲流,内部提高性能,实际上就是数据写或读到一个缓冲流中,再让系统写或读缓冲区的所有字节,不用的话一次写或读一个字节,数据量大时效率低
//会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节
is=new BufferedInputStream(new FileInputStream(file));
//通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
os=new BufferedOutputStream(new FileOutputStream("c:/copy.jpg"));
byte[] buf=new byte[1024];
int length;
while((length=is.read(buf, 0, buf.length))!=-1){
os.write(buf);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(is!=null){
is.close();
}
if(os!=null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件夹的拷贝:将一个文件夹(文件夹内包含的所有文件及文件夹)拷贝到另一个位置
package com.company.io.byteio;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 拷贝文件夹
* 递归遍历每一层的文件或文件夹
* 如果是文件夹目录,那么复制一份目录
* 遍历目录下的所有文件,是目录的,复制一份目录,是文件则复制到当前对应的目录下
*/
public class CopyDir {
public static void main(String[] args) {
copyDir(new File("c:/users/public"),new File("d:/a"));
}
//将source目录下的所有文件复制到destination下
public static void copyDir(File source,File destination){
//确保源文件夹目录存在和目标文件夹位置传入
if(!source.exists()||source==null||destination==null){
return;
}
if(source.isDirectory()){
//现在目标文件夹下新建一个目录,再递归遍历源文件当前的目录下的所有文件或文件夹
destination.mkdirs();
File[] files=source.listFiles();
if(files!=null){
for(File file:files){
copyDir(file,new File(destination,file.getName()));// c:/a/a d:/a
}
}
}else if(source.isFile()){
//直接复制文件到目标文件夹下的相应位置
copyFile(source,destination);
}
}
//复制文件
public static void copyFile(File source,File destination){
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
bis=new BufferedInputStream(new FileInputStream(source));
bos=new BufferedOutputStream(new FileOutputStream(destination));
byte[] buf=new byte[1024];
int length;
while((length=bis.read(buf))!=-1){
bos.write(buf);
bos.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try{
if(bis!=null){
bis.close();
}
if(bos!=null){
bos.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
字符流
package com.company.io.chario;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 文本输入输出流
*
*/
public class ReaderWriter {
public static void main(String[] args) {
copy(new File("c:/test.txt"),new File("c:/testcopy.txt"));
}
//复制文本文件
public static void copy(File src,File dest){
try {
BufferedReader br=new BufferedReader(new FileReader(src));
BufferedWriter bw=new BufferedWriter(new FileWriter(dest,true));
String line=null;
//字符缓冲输入流有个特有的方法,就是readLine()可以每次读取 一行数据
while((line=br.readLine())!=null){
System.out.println(line);
bw.write(line);//bw.append(line);
//字符缓冲输出流特有的方法,可以输出一个行分隔符
//行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 ('\n') 符。
bw.newLine();
bw.newLine();
bw.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
转换流
package com.company.io.convertio;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 乱码造成的原因
* 1、字节数不完整
* 2、编码与解码字符集不统一
*
* 转换流
* InputStreamReader
* 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。
* 它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
* 每次调用 InputStreamReader中的一个 read()方法都会导致从底层输入流读取一个或多个字节。
* 要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
* 为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。
*
* OutputStreamWriter
* OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。
* 它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
* 每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。
* 在写入底层输出流之前,得到的这些字节将在缓冲区中累积。
* 可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
* 为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。
*
*/
public class Demo1 {
public static void main(String[] args) {
BufferedReader br=null;
try {
//我这个txt是gbk编码格式,用utf-8读取出来中文变成了乱码
br=new BufferedReader(new InputStreamReader(new FileInputStream(new File("c:/test.txt")),"utf-8"));
char[] cbuf=new char[1024];
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节数组流
package com.company.io.other;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* 文件内容(不要过大)
* 读取 --->程序 -->到字节数组中
* 字节数组内容 -->程序 --> 输出到另外文件中
* 什么时候用?
*
*/
public class Demo1 {
public static void main(String[] args) {
//文件 到字节数组
byte[] data =fileToBytes("c:/5.jpg");
System.out.println(data.length);
//字节数组 文件中
bytesToFile(data,"c:/test.jpg");
}
//把文件转换为字节数组
private static byte[] fileToBytes(String path) {
FileInputStream fis=null;
ByteArrayOutputStream baos=null;
try {
fis=new FileInputStream(new File(path));
baos=new ByteArrayOutputStream();
byte[] buf=new byte[1024];
int length;
while((length=fis.read(buf))!=-1){
baos.write(buf,0,length);
baos.flush();
}
baos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}
//把字节数组转换为文件
private static void bytesToFile(byte[] data, String path) {
ByteArrayInputStream bais=null;
BufferedOutputStream bos=null;
try {
bais=new ByteArrayInputStream(data);
bos=new BufferedOutputStream(new FileOutputStream(new File(path)));
byte[] buf=new byte[1024];
int length;
while((length=bais.read(buf))!=-1){
bos.write(buf,0,length);
bos.flush();
}
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据流
package com.company.io.other;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 数据类型(基本+String) +数据
* 1、输入流: DataInputStream
* 2、输出流: DataOutputStream
* 异常: EOFException
*
*/
public class Demo2 {
public static void main(String[] args) {
File file=new File("c:/dataTest.txt");
writeByData(file);
readByData(file);
}
public static void readByData(File src){
try {
DataInputStream dis=new DataInputStream(new FileInputStream(src));
System.out.println(dis.readLong()+"--"+dis.readDouble()+"--"+dis.readUTF());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeByData(File dest){
DataOutputStream dos=null;
try {
dos=new DataOutputStream(new FileOutputStream(dest));
long num =88888L;
double pi =7.48;
String str ="看!天空飘荡着好多的充气娃——娃——呀!";
//数据+类型 写出文件中
dos =new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
//写出数据 注意顺序
dos.writeLong(num);
dos.writeDouble(pi);
dos.writeUTF(str);
dos.flush();
//关闭
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象流
package com.company.io.other;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import com.company.io.Employee;
/**
* 文件存储, 可以考虑字节数组
* 序列化:输出流 ObjectOutputStream
* 反序列化:输入流 ObjectInputStream 创建对象一种方式
*
* 解释一下序列化和反序列化,博文总结出来
*/
public class Demo3 {
public static void main(String[] args) {
try {
out();
read();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 反序列化
* ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
* ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时
* 可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。
* 其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
* @throws ClassNotFoundException
*/
public static void read() throws IOException, ClassNotFoundException{
ObjectInputStream ois =new ObjectInputStream(
new FileInputStream("c:/objectTest.txt"));
System.out.println(ois.readDouble());
Object obj =ois.readObject();
if(obj instanceof Employee){
Employee emp =(Employee)obj;
//name属性没序列化,是瞬时态数据,所以获取不到数据
System.out.println(emp.getName()+"-->"+emp.getSalary());
}
obj =ois.readObject();
if(obj instanceof int[]){
int[] arr =(int[])obj;
System.out.println(Arrays.toString(arr));
}
ois.close();
}
/**
* 序列化
* ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
* 可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
* 如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
* writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。
* 可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。
* 还可以使用 DataOutput 中的适当方法将基本数据类型写入流中。还可以使用 writeUTF 方法写入字符串。
* @throws IOException
*/
public static void out() throws IOException{
Employee emp =new Employee("丰乳肥臀",7000);
int[] arr ={520,748,4,555,9};
ObjectOutputStream oos =new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream("c:/objectTest.txt")));
oos.writeDouble(3.14);
oos.writeObject(emp);
oos.writeObject(arr);
oos.flush();
oos.close();
}
}
实体类
package com.company.io;
/**
* 雇员
* 1、不是所有的对象都可以序列化 Serializable
* 2、不是所有的属性都需要序列化 transient
*
*/
public class Employee implements java.io.Serializable{
private transient String name;
private double salary;
public Employee() {
}
public Employee(String name, double salary) {
super();
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
打印流
package com.company.io.other;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/**
* 打印流
*/
public class Demo4 {
public static void main(String[] args) throws FileNotFoundException {
//true表示为自动刷新,每当写入 byte 数组、调用其中一个 println 方法或写入换行符或字节 ('\n') 时都会刷新缓冲区
PrintStream ps=null;
try {
ps = new PrintStream(new FileOutputStream("c:/print.txt"),false,"gbk");
ps.print("hello my world!");
ps.println(true);
ps.println(101);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ps.close();
}
}
其他
package com.company.io.other;
import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Scanner;
/**
* 常量 重定向 了解
* System.in
* System.out
*
* System.setIn()
*/
public class Demo5 {
public static void main(String[] args) throws IOException {
System.out.println("我是普通日志");
System.err.println("我是错误日志,发现区别了么,打印出来看看");
setOut();
setIn();
}
/**
* 重定向输出
*/
public static void setOut() throws IOException {
System.setOut(new PrintStream("c:/111.txt"));
PrintStream ps =System.out;
ps.println("标准流重定向到输出流,我在文件里头");
ps.close();
//重定向回控制台
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
System.out.println("标准流又被重定向到了控制台,我在控制台");
}
/**
* 重定向输入
* @throws IOException
*/
public static void setIn() throws IOException {
//重定向 数据来源于、输出到控制台
System.setIn(new FileInputStream("c:/111.txt")); //文件
Scanner sc =new Scanner(System.in);
System.out.println(sc.nextLine());
//重定向回控制台
System.setIn(new FileInputStream(FileDescriptor.in));
sc =new Scanner(System.in);
System.out.println(sc.nextLine());
}
}
关于对象流和打印流我在简易多人聊天室程序的实现中,也有使用,可以参考。总结还没写,过几天贴上来。