fileInputStream
文件字节输入流读取文本会不可避免的出现汉字截断(三字节)乱码,每次读取多少个字节存多少到String:
long length=file.length;
bytes[] bytes=new bytes[(int)length]
new String(bytes[],0,fileInputStream.read(bytes))
jdk11的新增api:
//一次把文件所有的字节读取到一个字节数组中,可能内存不够
byte[] bytes = fileInputStream.readAllBytes();
System.out.println(new String(bytes));
但是,内存总比硬盘容量小,容易内存不够
fileOutStream
//加true可以追加内容
OutputStream fileOutputStream = new FileOutputStream("C:\\Users\\25130\\Desktop\\t2.txt",true);
byte[] bytes = "我爱你中国".getBytes();
fileOutputStream.write(97);
fileOutputStream.write(bytes);
fileOutputStream.write(bytes,0,12);
fileOutputStream.write("\r\n".getBytes());//加/r换行是为了兼容更多的平台
fileOutputStream.close();
复制文件案例
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("F:\\zipkin-server-2.24.0-exec.jar");
FileOutputStream fileOutputStream = new FileOutputStream("K:\\复制后的jar.jar");
byte[] bytes = new byte[1024];
int len;
while ((len=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.close();
fileInputStream.close();
System.out.println("复制完成");
System.out.println(new File("F:\\zipkin-server-2.24.0-exec.jar").length()/1024/1024+"MB");
}
新增资源释放方案
释放资源用finally代码块,不加finally,最后close,前面有异常也能执行,但是如果有return就直接退出方法,不执行close,如果close加在finally中,return之前要执行finally,所以finally中不能写return数据,catch中可以返回-1让代码编译通过,只有一种情况不执行finally,就是System.exit(0),终止jvm虚拟机
jdk7新增try with resource
try(定义资源对象){
}catch(){
}
FileReader
public static void main(String[] args) {
try (FileReader fileReader = new FileReader("C:\\Users\\25130\\Desktop\\t1.txt");
) {
int c;
while ((c=fileReader.read())!=-1){//一个个字符读,性能差
System.out.print((char)c);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
try (FileReader fileReader = new FileReader("C:\\Users\\25130\\Desktop\\t1.txt");
) {
char[] chars = new char[3];
int len,i = 0;
while((len=fileReader.read(chars))!=-1){
i++;
System.out.print(new String(chars,0,len));
}
System.out.println("\r\n读了"+i+"次");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
FileWriter
public static void main(String[] args) {
try (
FileWriter fileWriter = new FileWriter("C:\\Users\\25130\\Desktop\\t1.txt",true);
) {
fileWriter.write("\na");
fileWriter.write(97);
fileWriter.write('磊');
fileWriter.write("我爱你中国abc");
fileWriter.write("我爱你中国abc",0,5);
char[] chars={'i','t','黑','马','6'};
fileWriter.write(chars,2,2);//第3个开始读两个
} catch (IOException e) {
throw new RuntimeException(e);
}
}
输出流写数据的时候,必须flush才会生效,而close方法包含flush方法,这样设计的原因是让性能更好,创建一个缓冲区,写完数据到缓冲区(缓冲区满了会自动触发写入磁盘),只需要写入一次就能写到磁盘,关闭流后能继续使用流对象,flush后可以
缓冲流的作用:对原始流进行包装,以提高原始流的性能
在内存中开辟8kb的缓冲池,比原始流的速度快3~4倍,还可以设置缓冲池的大小,继续优化
BufferedInputStream&&BufferedOutputStream复制文件
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
FileInputStream fileInputStream = new FileInputStream("F:\\zipkin-server-2.24.0-exec.jar");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream,8192*2);
FileOutputStream fileOutputStream = new FileOutputStream("J:\\复制后的jar.jar");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream,8192*2);
byte[] bytes = new byte[1024];
int len;
while ((len=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,len);
}
bufferedOutputStream.close();
fileInputStream.close();
long end = System.currentTimeMillis();
System.out.println("复制完成,花费时间:"+(end-start)+"毫秒");
System.out.println(new File("F:\\zipkin-server-2.24.0-exec.jar").length()/1024/1024+"MB");
BufferedReader
bufferedReader.readLine()方法,一行行的读数据,返回String
public static void main(String[] args) {
try (FileReader fileReader = new FileReader("C:\\Users\\25130\\Desktop\\t1.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);) {
String line;
while((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
BufferedWriter
bufferdeWriter.newLine()方法,换行
原始流如果每次使用较大的字符数组读取数据,性能和缓冲流也能差不多,但是数组大小一定程度后会失效
InputStreamReader
public static void main(String[] args) {
try (FileInputStream fileInputStream = new FileInputStream("C:\\Users\\25130\\Desktop\\t1.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"GBK");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
) {
String line;
while((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
OutputStreamReader
指定用指定编码输出
1.String data="我爱你中国abc"
byte[] bytes=data.getBytes("GBK")
2.使用字符输出转换流:OutputStreamReader
public static void main(String[] args) {
try (FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\25130\\Desktop\\t1.txt",true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"gbk");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
) {
bufferedWriter.write("我是中国人abc");
bufferedWriter.write("我爱你中国abc");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
鎴戞槸涓浗浜篴bc鎴戠埍浣犱腑鍥絘bc我是中国人abc我爱你中国abc
PrintStream
打印97,文件中就是97
PrintStream构造器参数可以是File、String路径、OutputStream
public static void main(String[] args) {
try (PrintStream printStream = new PrintStream("C:\\Users\\25130\\Desktop\\t1.txt","utf-8");)
{
printStream.println(97);
printStream.println('a');
printStream.println("我爱你中国abc");
printStream.println(true);
printStream.println(99.5);
printStream.write(98);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
底层包含缓冲流
PrintWriter
PrintWrite继承Writer,支持写字符数据出去
PrintStream基础OutputStream,支持写字节数据出去
其他无区别
指定System.out.println()输出位置(默认是控制台)
public static void main(String[] args) {
System.out.println("老骥伏枥");
System.out.println("志在千里");
try (PrintStream printStream = new PrintStream("C:\\Users\\25130\\Desktop\\t1.txt");
) {
System.setOut(printStream);
System.out.println("烈士暮年");
System.out.println("壮心不已");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
DataInputStream
允许把数据和其类型一并读进来
public static void main(String[] args) {
try(DataInputStream dataInputStream = new DataInputStream(new FileInputStream("C:\\Users\\25130\\Desktop\\t1.txt"));
) {
int i = dataInputStream.readInt();
System.out.println(i);
double d = dataInputStream.readDouble();
System.out.println(d);
boolean b = dataInputStream.readBoolean();
System.out.println(b);
String rs = dataInputStream.readUTF();
System.out.println(rs);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
DataOutputStream
允许把数据和其类型一并写出去
public static void main(String[] args) {
try (DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("C:\\Users\\25130\\Desktop\\t1.txt"));){
dataOutputStream.writeInt(97);
dataOutputStream.writeDouble(99.5);
dataOutputStream.writeBoolean(true);
dataOutputStream.writeUTF("黑马666");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ObjectInputStream
将实体封装数据的实体从硬盘写到内存中(硬盘-> 内存 )
public static void main(String[] args) {
try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("C:\\Users\\25130\\Desktop\\t2.txt")))
{
User user = (User)objectInputStream.readObject();
user.setAge(22);
System.out.println(user);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
如果实体类没有实现Serializable接口,无法序列化,如果实体类没有定义
private static final long serialVersionUID=1L;
且在序列化一个类对象后,修改、新增、减少了这个类的字段,再反序列化会出现:
Caused by: java.io.InvalidClassException: io.User; local class incompatible: stream classdesc serialVersionUID = 9130766112716150713, local class serialVersionUID = 5921222291933542938
ObjectOutputStream
将实体封装数据的实体写到文件中(内存 -> 硬盘)
public static void main(String[] args) {
try (ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("C:\\Users\\25130\\Desktop\\t2.txt"));
) {
User user = new User("admin", "张三", 32, "666888xyz");
objectOutputStream.writeObject(user);
} catch (Exception e) {
throw new RuntimeException(e);
}
}