java io笔记_JAVA IO 第一次学习笔记

JAVA I/O流

I/O: input和output

流(Stream):数据传输的管道

I/O流的分类

1.按方向:输入流,输出流

2.按单位:字节流(操作所有类型),字符流(操作纯文本类型) 啥是纯文本,你能用记事本打开能看懂的就是纯文本文件

3.按功能:节点流(完成数据的传输读写),过滤流(增强其他流 的功能) (举例:比如电线,里面的金属丝是导电的,他是电线,但不能说外面的绝缘层胶皮他是电线,只是对金属丝的附带,节点流和过滤流的关系就和金属丝和绝缘外皮类似)

字节流

InputStream/OutputStream

字节输入输出流 父类(抽象类)

InputStream

//读一个字节 返回值:读取到的字节数据 返回-1 表示结束

public abstract int read()

//尝试读满byte数组 返回值:读到的字节个数 返回-1 表示结束 读取内容在byte数组中

public int read(byte b[])

//尝试读byte数组一段 返回值:读到的字节个数 返回-1 表示结束 读取内容在byte数组中

//start byte数组的第几位开始使用 len 从start开始第几位后都有效 不是截取文档意思

//ABCDEFG bs = new byte[10] read(bs,2,3) 后bs内容为 _ _ A B C _ _ _ _ _ 不是CDE 就是先读文档 取3个 从数组第二个位置开始放

public int read(byte b[], int start, int len)

public synchronized void reset()

示例代码

public static void main(String[] args) throws Exception{

InputStream in = new FileInputStream("a.txt");

/*int data = in.read();

System.out.println((char)data);*/

/*byte[] bytes = new byte[10];

while(true){

int len = in.read(bytes);

if (len == -1){

break;

}

for (int i = 0; i < len; i++) {

System.out.print(" "+(char)bytes[i]);

}

}*/

byte[] bytes = new byte[10];

while(true){

int len = in.read(bytes,2,7);

if (len == -1){

break;

}

for (int i = 0; i < len; i++) {

System.out.print(" "+(char)bytes[i]);

}

System.out.println();

}

in.close();

}

OutputStream

//写一个字符

public abstract void write(int b);

//写一组字符串

public void write(byte b[])

//截取字符串后,再写入文档

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

public void flush()

public void close()

示例代码

public static void main(String[] args) throws Exception{

//第二参数 追加 不覆盖 默认false

OutputStream out = new FileOutputStream("a.txt");

//out.write(65);

//out.write("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes(),2,3);

out.write("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes());

out.close();

}

FileInputStream/FileOutputStream

文件字节输入输出流(节点流) 会在磁盘上生成文件

FileInputStream

public FileInputStream(String name)

public FileInputStream(File file)

public FileChannel getChannel()

FileOutputStream

public FileOutputStream(String name)

public FileOutputStream(String name, boolean append)

public FileOutputStream(File file)

public FileOutputStream(File file, boolean append)

public FileChannel getChannel()

DataInputStream/DataOutputStream

数据输入流 (过滤流) 普通节点流无法写入特定数据类型,包含了基本类型的写入读取方法

DataInputStream

public DataInputStream(InputStream in)

public final boolean readBoolean()

public final byte readByte()

public final char readChar()

public final double readDouble()

public final float readFloat()

public final int readInt()

public final long readLong()

public final short readShort()

public final String readUTF()

DataOutputStream

public DataOutputStream(OutputStream out)

public final void writeBoolean(boolean v)

public final void writeByte(int v)

public final void writeBytes(String s)

public final void writeChar(int v)

public final void writeChars(String s)

public final void writeDouble(double v)

public final void writeFloat(float v)

public final void writeInt(int v)

public final void writeLong(long v)

public final void writeShort(int v)

public final void writeUTF(String str)

示例代码(存储Long类型)

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("c.txt");

long a = 12391823897298739L;

//强转换后 是17个字节 用记事本可以看懂内容

//fos.write((a+"").getBytes());

DataOutputStream out = new DataOutputStream(fos);

//用了过滤流 就是long的8个字节 用记事本看不懂内容

out.writeLong(a);

out.close();

}

ObjectInputStream/ObjectOutputStream

对象输入输出流(过滤流) 他也有DataOutputStream的八大类型读取方法 自带缓冲区

通过流传输对象,对象需要实现序列化接口

ObjectInputStream

public ObjectInputStream(InputStream in)

public final Object readObject()

ObjectOutputStream

public ObjectOutputStream(OutputStream out)

public final void writeObject(Object obj)

示例代码(存储对象类型)

对象输入输出流操作演示,对象的流传输以及结束读取不是-1 而是捕获异常,transient声明属性 不参与序列化

public class Test1 {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("obj.txt");

ObjectOutputStream out = new ObjectOutputStream(fos);

Student s1 = new Student("张飞", 45, 60);

Student s2 = new Student("公孙离", 25, 70);

out.writeObject(s1);

out.writeObject(s2);

out.close();

FileInputStream fis = new FileInputStream("obj.txt");

ObjectInputStream in = new ObjectInputStream(fis);

//Object o1 = in.readObject();

//Object o2 = in.readObject();

try {

while(true){

Object o = in.readObject();

System.out.println(o);

}

} catch (EOFException e) {

//文件读取完毕 不是返回-1 而是报EOF异常 需要手动捕获结束

System.out.println("文件读取完毕");

}finally{

in.close();

}

}

static class Student implements Serializable {

String name;

int age;

transient int scope;

public Student(String name, int age, int scope) {

this.name = name;

this.age = age;

this.scope = scope;

}

@Override

public String toString() {

return "student{" +

"name='" + name + '\'' +

", age=" + age +

", scope=" + scope +

'}';

}

}

}

BufferedInputStream/BufferedOutputStream

缓冲输入输出流 (过滤流) 将数据读取到缓冲区 读满再统一拿出来 减少磁盘操作 时间更快 缓冲区默认8K

BufferedInputStream

public BufferedInputStream(InputStream in) {

this(in, 8192);

}

BufferedOutputStream

public BufferedOutputStream(OutputStream out) {

this(out, 8192);

}

示例代码(缓冲流复制文件)

文件复制,利用缓冲流 比常规的速度还快

public static void copyFile3(String srcName, String destName) throws Exception {

InputStream fis = new FileInputStream(srcName);

BufferedInputStream in = new BufferedInputStream(fis);

OutputStream fos = new FileOutputStream(destName);

BufferedOutputStream out = new BufferedOutputStream(fos);

byte[] bs = new byte[1024];

while(true){

int len = in.read(bs);

if(len == -1){

break;

}

out.write(bs,0,len);

}

in.close();

out.close();

}

Serializable

序列化,将虚拟机中的对象打散,转换为字节序列存储到磁盘空间(实际文件)中, 反之,将磁盘空间中数据按照之前打散的顺序,在虚拟机中组装成对象,称之为反序列化;要想对象能在流中传输就得实现Serializable接口

public interface Serializable{}

Serializable,空接口(标记接口),类实现Serializable后,在虚拟机看来,就会看见这个类 ,上写了个大字 “拆” 画了个圈。然后虚拟机就会知道,这个类可以拆,可以序列化。

示例代码(反序列化和构造函数)

反序列化实现serializable接口时,不再调用构造方法,而是根据默认的序列化规则时进行创建,不实现接口调用无参数构造方法

public class Test2 {

public static void main(String[] args) throws Exception {

/*FileOutputStream fos = new FileOutputStream("a.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

B b = new B();

out.writeObject(b);

out.close();*/

FileInputStream fis = new FileInputStream("a.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Object o = in.readObject();

in.close();

System.out.println(o instanceof B);

}

}

class A{

public A(){

System.out.println("A()");

}

}

class B extends A implements Serializable{

public B(){

System.out.println("B()");

}

}

自定义序列化

1.实现Externalizable接口

public interface Externalizable extends java.io.Serializable{

void writeExternal(ObjectOutput out) throws IOException;

void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

}

示例代码

实现 Externalizable 接口,复写readExternal,writeExternal方法,非默认序列化 需要无参构造支持

package com.nesc.servlet;

import java.io.*;

/**

* 自定义序列化 实现 Externalizable 接口

*

* @author wanghl

* @date 2020/10/26 14:49

**/

public class TestExternalizable {

public static void main(String[] args) throws Exception{

Student student = new Student(20, "苏宇");

FileOutputStream fos = new FileOutputStream("stu.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

out.writeObject(student);

out.close();

FileInputStream fis = new FileInputStream("stu.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Object o = in.readObject();

in.close();

System.out.println(o);

}

}

class Student implements Externalizable{

int age;

String name;

public Student(){

System.out.println("student()");

}

public Student(int age, String name) {

this.age = age;

this.name = name;

}

@Override

public String toString() {

return "Student{" +

"age=" + age +

", name='" + name + '\'' +

'}';

}

/**

* 自定义序列化 写规则 age*2

* @param out

* @throws IOException

*/

@Override

public void writeExternal(ObjectOutput out) throws IOException {

out.writeInt(age*2);

out.writeUTF(name);

}

/**

* 自定义序列化 读规则 name 如果看见苏宇 就改成 苏大傻

* @param in

* @throws IOException

* @throws ClassNotFoundException

*/

@Override

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

age = in.readInt();

name = in.readUTF();

if("苏宇".equals(name)){

name = "苏大傻";

}

}

}

输出结果

无参构造 student()

结果打印 Student{age=40, name='苏大傻'}

2.实现Serializable接口,写下面的方法

private Object writeReplace() throws ObjectStreamException {

return this;

}

private void writeObject(java.io.ObjectOutputStream out) throws IOException {}

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {}

private Object readResolve() throws ObjectStreamException {

return this;

}

代码示例

自定义四个方法,可自己随意改

package com.nesc.servlet;

import java.io.*;

/**

* 自定义序列化 实现Serializable 写writeReplace writeObject readObject readResolve 方法

*

* @author wanghl

* @date 2020/10/26 15:09

**/

public class AutoSerializableTest implements Serializable {

private String name;

private int age;

@Override

public String toString() {

return "AutoSerializableTest{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

public AutoSerializableTest(String name, int age) {

this.name = name;

this.age = age;

}

/**

* 修改写对象 我把要写的对象 name 属性给改了

* @return

* @throws ObjectStreamException

*/

private Object writeReplace() throws ObjectStreamException {

this.name = "猜猜我是谁";

System.out.println("1 writeReplace " + this);

return this;

}

/**

* 向文件中写入数据 你对象爱咋改咋改 我写我自己的

* @param out

* @throws IOException

*/

private void writeObject(ObjectOutputStream out) throws IOException {

out.writeUTF("柳文彦");

out.writeInt(120);

System.out.println("2 writeObject ");

}

/**

* 从文件中读取到的对象属性 属性自己可以改

*

* @param in

* @throws IOException

* @throws ClassNotFoundException

*/

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {

name = in.readUTF();

age = in.readInt();

System.out.println("3 readObject name=" + name +",age ="+ age );

age = 100;

}

/**

* 最终呈现的对象属性

* @return

* @throws ObjectStreamException

*/

private Object readResolve() throws ObjectStreamException {

System.out.println("4 readResolve " + this);

this.name = "苏宇变的";

this.age = 20;

return this;

}

public static void main(String[] args) throws Exception{

AutoSerializableTest instance = new AutoSerializableTest("苏宇",20);

FileOutputStream fos = new FileOutputStream("auto.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

out.writeObject(instance);

out.close();

FileInputStream fis = new FileInputStream("auto.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Object o = in.readObject();

in.close();

System.out.println("5 "+ o);

}

}

输出结果

1 writeReplace AutoSerializableTest{name='猜猜我是谁', age=20}

2 writeObject

3 readObject name=柳文彦,age =120

4 readResolve AutoSerializableTest{name='柳文彦', age=100}

5 AutoSerializableTest{name='苏宇变的', age=20}

3.第三方序列化工具

实际应用基本上都是用的第三方的序列化工具

浅克隆与深克隆

克隆:你有啥,我有啥,咱俩一模一样

浅克隆:基本类型值都一样,对象属性一样,地址相同

深克隆:基本类型值一样。对象属性一样,地址不同。

对象克隆步骤:1.复写object类的clone方法,进行public提权;2.实现Cloneable接口进行标记,该对象可以克隆

示例代码(相同对象连续存储)

连续存储相同对象,第二次不在存储对象内容,而是存储上一个对象的索引的东西,读取的时候读到第二个,然后直接把第一个对象地址给出去,所以读取到的两个对象地址一样

public class CloneTest {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("worker.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

Worker worker = new Worker("鲁班七号", 22);

//连续两次存储相同对象

out.writeObject(worker);

//这里改了也不行,对象地址没变 下面不认

worker.age = 44;

out.writeObject(worker);

out.close()

FileInputStream fis = new FileInputStream("worker.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Object o1 = in.readObject();

Object o2 = in.readObject();

in.close();

//结果为 true

System.out.println(o1 == o2);

}

}

class Worker implements Serializable{

String name;

int age;

public Worker(String name, int age) {

this.name = name;

this.age = age;

}

@Override

public String toString() {

return "Worker{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

实例代码(浅克隆)

按上述所说,同一个对象改属性都不认,如果真有需求需要存储两个一样对象,还是非同地址的,这时候需要进行克隆,尤其是对象属性多,类型复杂的

public class CloneTest {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("worker.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

Address address = new Address();

Worker worker = new Worker("鲁班七号", 22, address);

//连续两次存储相同对象

out.writeObject(worker);

//这里改了也不行,对象地址没变 下面不认

Worker worker2 = (Worker) worker.clone();

worker2.age = 44;

out.writeObject(worker2);

out.close();

FileInputStream fis = new FileInputStream("worker.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Worker o1 = (Worker)in.readObject();

Worker o2 = (Worker)in.readObject();

in.close();

//结果false

System.out.println(o1 == o2);

//结果true 浅克隆 直接把对象地址复制走了

System.out.println(o1.address == o2.address);

}

}

class Worker implements Serializable,Cloneable{

String name;

int age;

Address address;

public Worker(String name, int age,Address address) {

this.name = name;

this.age = age;

this.address = address;

}

@Override

public String toString() {

return "Worker{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

@Override

public Object clone() throws CloneNotSupportedException {

return super.clone();

}

}

class Address implements Serializable{

}

实例代码(深克隆)

思路:重写clone方法,把对象经由IO流,把对象地址转换为对象实际内容,再反序列化回来,就是一个新的对象

下面代码提供了两版,FileInputStream 和 ByteArrayInputStream ,后者更快 更好,下面会具体介绍这个类

public class CloneTest {

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("worker.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

Address address = new Address();

Worker worker = new Worker("鲁班七号", 22, address);

//连续两次存储相同对象

out.writeObject(worker);

//这里改了也不行,对象地址没变 下面不认

Worker worker2 = (Worker) worker.clone();

worker2.age = 44;

out.writeObject(worker2);

out.close();

FileInputStream fis = new FileInputStream("worker.dat");

ObjectInputStream in = new ObjectInputStream(fis);

Worker o1 = (Worker)in.readObject();

Worker o2 = (Worker)in.readObject();

in.close();

//结果false

System.out.println(o1 == o2);

//结果false 深克隆 重新clone方法创建 一个新对象

System.out.println(o1.address == o2.address);

}

}

class Worker implements Serializable,Cloneable{

String name;

int age;

Address address;

public Worker(String name, int age,Address address) {

this.name = name;

this.age = age;

this.address = address;

}

@Override

public String toString() {

return "Worker{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

@Override

public Object clone() throws CloneNotSupportedException {

Object o = null;

try {

//利用FileOutputStream 进行转换 需要生成中间文件 效率慢

/*FileOutputStream fos = new FileOutputStream("temp.dat");

ObjectOutputStream out = new ObjectOutputStream(fos);

out.writeObject(this);

out.close();

FileInputStream fis = new FileInputStream("temp.dat");

ObjectInputStream in = new ObjectInputStream(fis);

o = in.readObject();

in.close();*/

//利用ByteArrayOutputStream 数组存储 不出虚拟机 不需要访问磁盘

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream out = new ObjectOutputStream(bos);

out.writeObject(this);

//最终内容存放到bs数组中

byte[] bs = bos.toByteArray();

out.close();

ByteArrayInputStream bis = new ByteArrayInputStream(bs);

ObjectInputStream in = new ObjectInputStream(bis);

o = in.readObject();

in.close();

} catch (Exception e) {

e.printStackTrace();

}

return o;

}

}

class Address implements Serializable{

}

ByteArrayInputStream/ByteArrayOutputStream

字节数组输入输出流,在内存中生成一片空间,写入读取不需要访问磁盘空间

ByteArrayInputStream

public ByteArrayInputStream(byte buf[]) {

this.buf = buf;

this.pos = 0;

this.count = buf.length;

}

ByteArrayOutputStream

public synchronized byte toByteArray()[] {

return Arrays.copyOf(buf, count);

}

字符流

Reader/Writer

字符输入输出流 父类 ,抽象类

Reader

public int read()

public int read(char cbuf[])

public int read(char cbuf[], int off, int len)

public int read(java.nio.CharBuffer target)

Writer

public void write(char cbuf[])

public void write(char cbuf[], int off, int len)

public void write(int c)

public void write(String str)

public void write(String str, int off, int len)

FileReader/FileWriter

文件字符输入输出流, 用法对应文件字节流 节点流

FileReader

public FileReader(File file)

public FileReader(FileDescriptor fd)

public FileReader(String fileName)

FileWriter

public FileWriter(File file)

public FileWriter(File file, boolean append)

public FileWriter(FileDescriptor fd)

public FileWriter(String fileName)

public FileWriter(String fileName, boolean append)

示例代码

public static void main(String[] args) throws Exception {

FileWriter fw = new FileWriter("fileWriter.txt");

fw.write("海上生明月");

fw.close();

FileReader fr = new FileReader("fileWriter.txt");

char[] cs = new char[1024];

while(true){

int read = fr.read(cs, 0, cs.length);

if(read ==-1){

break;

}

System.out.println(cs);

}

fr.close();

}

BufferdReader/BufferdWriter

字符缓冲输入输出流 过滤流

BufferdReader

public BufferedReader(Reader in)

public BufferedReader(Reader in, int sz)

public int read(char cbuf[], int off, int len)

public String readLine()

BufferdWriter

public BufferedWriter(Writer out)

public BufferedWriter(Writer out, int sz)

public void write(char cbuf[], int off, int len)

public void write(int c)

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

示例代码

public static void main(String[] args) throws Exception {

FileWriter fw = new FileWriter("fileWriter.txt");

BufferedWriter bw = new BufferedWriter(fw);

bw.write("海上生明月");

bw.close();

FileReader fr = new FileReader("fileWriter.txt");

BufferedReader br = new BufferedReader(fr);

while(true){

String str = br.readLine();

if(str == null){

break;

}

System.out.println(str);

}

br.close();

}

PrintWriter

缓冲输出流 类似BufferdWriter 有各种基本类型输出

public PrintWriter(File file)

public PrintWriter(OutputStream out)

public PrintWriter(String fileName)

public PrintWriter (Writer out)

public void println(boolean x)

public void println(char x)

public void println(char x[])

public void println(double x)

public void println(Object x)

public void println(String x)

//... 其他基本类型 和 print 方法

InputStreamReader/OutputStreamWriter

桥转换 字节流转换字符流 同时可设置编解码字符集

InputStreamReader

public InputStreamReader(InputStream in)

public InputStreamReader(InputStream in, Charset cs)

public InputStreamReader(InputStream in, CharsetDecoder dec)

public InputStreamReader(InputStream in, String charsetName)

public String getEncoding()

OutputStreamWriter

public OutputStreamWriter(OutputStream out)

public OutputStreamWriter(OutputStream out, Charset cs)

public OutputStreamWriter(OutputStream out, CharsetEncoder enc)

public OutputStreamWriter(OutputStream out, String charsetName)

public String getEncoding()

File

File 类 操作的是文件或文件夹的权限(只读、改名、删除、新建等),IO流操作的内容

public File(String pathname)

public boolean createNewFile()

public boolean delete()

public boolean exists()

public String getAbsolutePath()

public String getName()

public boolean isDirectory()

public boolean isFile()

public File[] listFiles(FileFilter filter)

public File[] listFiles()

public boolean mkdir()

public boolean renameTo(File dest)

public boolean setReadOnly()

NIO

jdk1.4 以后出现的,new io ,非阻塞IO

Buffer

用于特定原始类型的数据的容器

Buffer 三个指针 position limit capacity

public final Buffer flip() //写模式 变 读模式 position = 0

public final Buffer clear() //读模式 变 写模式 position = 0;limit =0

ByteBuffer

public static ByteBuffer allocate(int capacity)

public static ByteBuffer wrap(byte[] array)

public final ByteBuffer put(byte[] src) //...其他类型put

public ByteBuffer get(byte[] dst) //...其他类型get

示例代码

public static void main(String[] args) throws Exception {

FileOutputStream fos = new FileOutputStream("nio.txt");

FileChannel channel = fos.getChannel();

ByteBuffer bb = ByteBuffer.wrap("hello world".getBytes());

channel.write(bb);

channel.close();

FileInputStream fis = new FileInputStream("nio.txt");

channel = fis.getChannel();

ByteBuffer byteBuffer = ByteBuffer.allocate(5);

byte[] array = byteBuffer.array();

while(true){

int read = channel.read(byteBuffer);

if(read ==-1){

break;

}

byteBuffer.flip();

//当limit = position的时候 认为没有下一个元素了

while(byteBuffer.hasRemaining()){

System.out.print((char) byteBuffer.get());

}

byteBuffer.clear();

}

channel.close();

}

FileChannel

用于读取,写入,映射和操作文件的通道。

public abstract int read(ByteBuffer dst)

public abstract long size()

public abstract int write(ByteBuffer src)

public abstract MappedByteBuffer map(MapMode mode, long position, long size)

Charset

字符编码集 有编码解码相应方法

public final CharBuffer decode(ByteBuffer bb)

public final ByteBuffer encode(CharBuffer cb)

public final ByteBuffer encode(String str)

public static Charset forName(String charsetName)

示例代码

public static void main(String[] args) throws Exception {

Charset cs = Charset.forName("GBK");

ByteBuffer byteBuffer = cs.encode("大河之剑天上来");

CharBuffer cb = cs.decode(byteBuffer);

System.out.println(cb.toString());

}

文件复制

结论,nio中 FileChannel 的 transferTo 最快 见copyFile6

示例代码

public class FileCopyTest {

public static void main(String[] args) throws Exception {

copyFile1("a.txt","b.txt");

copyFile2("a.txt","c.txt");

copyFile3("a.txt","d.txt");

copyFile4("a.txt","e.txt");

copyFile5("a.txt","f.txt");

copyFile6("a.txt","g.txt");

}

public static void copyFile1(String srcName, String destName) throws Exception {

InputStream fis = new FileInputStream(srcName);

OutputStream fos = new FileOutputStream(destName);

while(true){

int data = fis.read();

if(data == -1){

break;

}

fos.write(data);

}

fis.close();

fos.close();

}

public static void copyFile2(String srcName, String destName) throws Exception {

InputStream fis = new FileInputStream(srcName);

OutputStream fos = new FileOutputStream(destName);

byte[] bs = new byte[1024];

while(true){

int len = fis.read(bs);

if(len == -1){

break;

}

fos.write(bs,0,len);

}

fis.close();

fos.close();

}

public static void copyFile3(String srcName, String destName) throws Exception {

InputStream fis = new FileInputStream(srcName);

BufferedInputStream in = new BufferedInputStream(fis);

OutputStream fos = new FileOutputStream(destName);

BufferedOutputStream out = new BufferedOutputStream(fos);

byte[] bs = new byte[1024];

while(true){

int len = in.read(bs);

if(len == -1){

break;

}

out.write(bs,0,len);

}

in.close();

out.close();

}

public static void copyFile4(String srcName, String destName) throws Exception {

FileInputStream fis = new FileInputStream(srcName);

FileChannel channel1 = fis.getChannel();

FileOutputStream fos = new FileOutputStream(destName);

FileChannel channel2 = fos.getChannel();

ByteBuffer bb = ByteBuffer.allocate(1024);

while(true){

int len = channel1.read(bb);

if(len == -1){

break;

}

//切换 读模式 读取到 position 游标处结束 positon 不直接等与 capacity 所以不涉及最后一次 多读取

bb.flip();

channel2.write(bb);

//切换 写模式 position=0 limit=0

bb.clear();

}

channel1.close();

channel2.close();

}

public static void copyFile5(String srcName, String destName) throws Exception {

FileInputStream fis = new FileInputStream(srcName);

FileChannel channel1 = fis.getChannel();

FileOutputStream fos = new FileOutputStream(destName);

FileChannel channel2 = fos.getChannel();

//把文件整个映射到内存当中 相当于 一次直接搬走

MappedByteBuffer map = channel1.map(FileChannel.MapMode.READ_ONLY, 0, channel1.size());

int read = channel2.read(map);

channel1.close();

channel2.close();

}

public static void copyFile6(String srcName, String destName) throws Exception {

FileInputStream fis = new FileInputStream(srcName);

FileChannel channel1 = fis.getChannel();

FileOutputStream fos = new FileOutputStream(destName);

FileChannel channel2 = fos.getChannel();

//最快方法

channel1.transferTo(0, channel1.size(), channel2);

channel1.close();

channel2.close();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值