在操作文件流的时候尽量避免使用缓存流,非文本文件也要尽量避免使用字符流!
字节流
FileInputStream
第一种方式(一个一个读)
package com.company;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class IOUtil {
/**
* 读取文件内容,16位输出到控制台
* 没输出10个换行
*
* @param fileName
*/
public static void printHex(String fileName) {
// File file=new File(fileName);
try {
//把文件作为字节流进行读操作
FileInputStream in = new FileInputStream(fileName);
List<Byte> list=new ArrayList<>();
int b;
int i = 0;
while ((b = in.read())!=-1){
if (b<=0xf){
//单位数前面补0
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+",");
list.add((byte) b);
if (++i%10==0){
System.out.println();
}
}
in.close();
System.out.println();
byte[] bytes = new byte[list.size()];
for (int j = 0; j < list.size(); j++) {
bytes[j]=list.get(j);
}
String s=new String(bytes,"gbk");
System.out.println(s);
// FileInputStream in=new FileInputStream(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
IOUtil.printHex("/Users/Johnson/Desktop/JAVA/test.txt");
ce,d2,be,cd,ca,c7,cb,a7,2c,ce,
d2,ce,e4,b9,a6,d7,ee,c0,f7,ba,
a6,
我就是帅,我武功最厉害
第二种方式(多个读)
public static void printHexByByteArray(String filename) {
try {
FileInputStream in = new FileInputStream(filename);
byte[] bytes = new byte[20 * 1024];//20k
//从in中批量读取字节,放入到bytes数组中,从第0个位置开始,最多放bytes.length个,返回的是读取到的个数
// in.read(bytes,0,bytes.length);//一次性读完,说明字节数组足够大
int j = 0;
int num;
while ((num = in.read(bytes, 0, bytes.length)) != -1) {//每次读20k,一次性读不完的时候
for (int i = 0; i < num; i++) {
System.out.print(Integer.toHexString(bytes[i] & 0xff)+",");
if (++j%10==0){
System.out.println();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
FileOutStream
public static void writeByte(String fileName) {
try {
//如果文件存在,则直接创建文件,
// 如果不存在,每次创建一个FileOutputStream都会先删除再创建,
// write过程中,多次write,如果使用同一个FileOutputStream,不会覆盖
// 如果append是true,则不会先删除再创建,直接在后面写
FileOutputStream out = new FileOutputStream(fileName,true);//boolean append,是否追加, 默认false
out.write('A');//写出了A字符的低八位,一共16位,2个字节
out.write('B');//写出了B字符的低八位,一共16位,2个字节
int a = 10;//write只能写低八位,写一个整数需要四次低八位
out.write(a >>> 24 & 0xff);
out.write(a >>> 16 & 0xff);
out.write(a >>> 8 & 0xff);
out.write(a >>> 0 & 0xff);
byte[] gbks = "中国".getBytes("gbk");
out.write(gbks);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
结合实现复制功能
public static void copyFile(String fileName,String TargetName){
File srcFile=new File(fileName);
if (!srcFile.exists()){
throw new IllegalArgumentException("文件"+srcFile+"不存在");
}
if (!srcFile.isFile()){
throw new IllegalArgumentException("文件"+srcFile+"不是文件");
}
try {
FileInputStream in = new FileInputStream(fileName);
FileOutputStream out = new FileOutputStream(TargetName,true);
byte[] bytes = new byte[20 * 1024];//20k
//从in中批量读取字节,放入到bytes数组中,从第0个位置开始,最多放bytes.length个,返回的是读取到的个数
// in.read(bytes,0,bytes.length);//一次性读完,说明字节数组足够大
int j = 0;
int num;
while ((num = in.read(bytes, 0, bytes.length)) != -1) {//每次读20k,一次性读不完的时候
// for (int i = 0; i < num; i++) {
// System.out.print(Integer.toHexString(bytes[i] & 0xff) + ",");
// if (++j % 10 == 0) {
// System.out.println();
// }
// }
out.write(bytes,0,num);
out.flush();// 最好加上
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
DataOutputStream
public static void writeData(String fileName){
try {
//对八种基本数据的封装
DataOutputStream out=new DataOutputStream(new FileOutputStream(fileName));
out.writeInt(10);
out.writeInt(-10);
out.writeLong(25515);
out.writeDouble(234.55);
out.writeUTF("中国");//utf-8
out.writeChars("中国");//utf-16be
out.close();
}catch (IOException e){
e.printStackTrace();
}
}
DataInputStream
public static void readData(String fileName){
try {
//对八种基本数据的封装
DataInputStream in=new DataInputStream(new FileInputStream(fileName));
int i = in.readInt();
System.out.println(i);
i = in.readInt();
System.out.println(i);
long l = in.readLong();
System.out.println(l);
double d = in.readDouble();
System.out.println(d);
String s = in.readUTF();
System.out.println(s);
in.close();
}catch (IOException e){
e.printStackTrace();
}
}
BufferedOutStream(最优写法)
public static void copyFileByBuffer(String fileName, String TargetName) {
File srcFile = new File(fileName);
File targetFile = new File(TargetName);
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件" + srcFile + "不存在");
}
if (!srcFile.isFile()) {
throw new IllegalArgumentException("文件" + srcFile + "不是文件");
}
InputStream inputStream = null ;
BufferedInputStream bufferedInputStream = null ;
OutputStream outputStream = null ;
BufferedOutputStream bufferedOutputStream = null ;
try {
inputStream = new FileInputStream( srcFile ) ;
bufferedInputStream = new BufferedInputStream( inputStream ) ;
outputStream = new FileOutputStream( targetFile ) ;
bufferedOutputStream = new BufferedOutputStream( outputStream ) ;
byte[] b=new byte[1024]; //代表一次最多读取1KB的内容
int length = 0 ; //代表实际读取的字节数
while( (length = bufferedInputStream.read( b ) )!= -1 ){
//length 代表实际读取的字节数
bufferedOutputStream.write(b, 0, length );
}
//缓冲区的内容写入到文件
bufferedOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {
if( bufferedOutputStream != null ){
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( bufferedInputStream != null){
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if( inputStream != null ){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if ( outputStream != null ) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流
FileWrite/FileReader不能写编码
最优写法
public static void copyByBrAndBw(String srcName,String targetName){
BufferedReader bufferedReader=null;
BufferedWriter bufferedWriter=null;
try {
bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream(srcName),"gbk"));
bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetName)));
String line;
while ((line=bufferedReader.readLine())!=null){
System.out.print(line);
System.out.println();
bufferedWriter.write(line);
bufferedWriter.newLine();
}
//缓冲区的内容写入到文件
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedWriter!=null){
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
第二种写法
public static void copyByIrAndOw(String srcName,String targetName){
InputStreamReader inputStreamReader=null;
OutputStreamWriter outputStreamWriter=null;
try {
inputStreamReader=new InputStreamReader(new FileInputStream(srcName),"gbk");
outputStreamWriter=new OutputStreamWriter(new FileOutputStream(targetName));
char[] chars=new char[4*1024];//4k
int num;
while ((num=inputStreamReader.read(chars,0,chars.length))!=-1){
String s=new String(chars,0,num);
System.out.println(s);
outputStreamWriter.write(chars,0,num);
}
//缓冲区的内容写入到文件
outputStreamWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (inputStreamReader!=null){
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStreamWriter!=null){
try {
outputStreamWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
序列化
File file = new File("/Users/Johnson/Desktop/JAVA/obj.dat");
// if (!file.exists()){
// file.createNewFile();
// }
// ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("/Users/Johnson/Desktop/JAVA/obj1.dat"));
// Student student=new Student("Johnson",1,25);
// objectOutputStream.writeObject(student);
// objectOutputStream.close();
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("/Users/Johnson/Desktop/JAVA/obj1.dat"));
try {
Student student=(Student)objectInputStream.readObject();
System.out.println(student);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
package com.company;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int no;
//该元素不会用jvm进行序列化,也可以自身进行序列化
private transient int age;
public Student(String name,
int no,
int age) {
super();
this.name=name;
this.no=no;
this.age=age;
}
@Override
public String toString() {
return "name:"+name+",no:"+no+",age"+age;
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm默认可以序列化的进行序列化
s.writeObject(age);//自己完成age的序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{
s.defaultReadObject();//把jvm默认可以序列化的进行反序列化
this.age= (int) s.readObject();//自己完成age的反序列化
}
}