java-IO流、多线程

IO流


    IO流概述:
        I 表示input,是数据从硬盘文件读入到内存的过程,称之为输入,负责读。
        O 表示 output,是内存程序的数据从内存到写出到硬盘文件的过程,称之为输出,负责写。
    流的4大类:
        字节流:
            字节输入流:
                以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。
                    方法:
                        FileInputStream(File file)   通过打开与实际文件的连接来创建一个,该文件由文件系统中的File 对象命名file。
                        FileInputStream(String name)   通过打开与实际文件的连接来创建一个,该文件由name 文件系统中的路径名命名。
                        public  int  read () 从此输入流中读取一个字节的数据。
                        int  read(byte[] b)  从此输入流中读取最多字节的数据到字节数组中。
            字节输出流:
                以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流称为字节输出流。
                    方法:
                        public void write(int a)    写一个字节出去
                        public  void write(byte [] buffer)    写一个字节数组出去
                        public void write (byte[] buffer,int pos, int len)    写一个字节数组的一部分出去
                    字节输出流如何实现数据追加:
                        new FileOutputStream("C:/Flying/aaa/1.txt",true);
                    字节输出流如何实现写出去的数据能换行:
                        os.write("\r\n".getBytes());
                    如何让写出去的数据能够生效:
                        flush()刷新数据
                        close()方法是关闭流,关闭包含刷新,关闭流之后就不可以再继续使用了。
        字符流:
            字符输入流(读写字节数据的):
                以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。
                    方法:
                        public int read()    每次读取单个字符返回,如果字节没有可读 返回-1
                        public int read (char[] buffer)   每次读取一个数组,返回读取的字符数,如果字节没有可读 返回-1
            字符输出流(读写字符数据的):
                以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流称为字符输出流。
                    方法:
                        void write(int c)  写一个字符
                        void write(char[] cbuf)   写入一个字符数组 
                        void  write (char[] cbuf,int off, len)    写入字符数组的一部分
                        void write(String str)    写一个字符串
                        void write(String str,int off, int len)    写一个字符串的一部分
    练习:
        

public class Test6 {
    public static void main(String[] args) {
        //使用IO流读取视频文件到指定磁盘
        try {
            BufferedInputStream  bis = new BufferedInputStream(new FileInputStream(new File("C:\\Flying\\aaa\\ddd\\eee\\455.png")));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Flying\\99.png")));
            byte [] b = new byte[1024];
            int len;
            while((len = bis.read(b)) != -1) {
                bos.write(b);
            }
            
            bis.close();
            bos.close();
            System.out.println("完成");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

多线程

多线程
    概念:
        多线程是什么?
            多线程是指从软硬件上实现多条执行流程的技术。
        多线程用在哪里,有什么好处?
            生活中的例子:12306多人购票、百度网盘的上传下载、消息通讯、淘宝京东等系统都离不来多线程技术。
        进程是一个完整的程序, 线程是进程里面执行的一个功能;一个进程里面有多个线程;进程申请的是系统资源;线程申请的是进程的资源。线程是进程的最小基本单位。
    并发与并行
        概念:
            正在运行的程序(软件)就是一个独立的进程,线程是属于进程的,多个线程其实是并发与并行同时进行的。多线程是抢占式运行的。
        并发的理解:同时发生,交替执行
            CPU同时处理线程的数量有限。
            CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程是在同时执行,这就是并发。
        并行的理解:
            在同一个时刻上,同时有多个线程在被CPU处理并执行。(同一个时刻同时在执行)
    Thread类
        java是通过java.lang.Thread类来代表线程的。
        按照面向对象的思想,Thread类应该提供了实现多线程的方式。
    多线程的实现方式一:继承Thread类
        1.定义一个子类MyThread继承线程类Thread,重写Run方法。
        2.创建MyThread类对象
        3.调用线程对象的start方法启动线程(启动后还是执行run方法)
注意⚠️:不要把主线程任务放在子线程之前了;否则相当于一个单线程效果。
        4.练习:
             public class Demo1 {
    public static void main(String[] args) {
        //目标: 创建线程的第一种方式

        //3.创建MyThread对象
        MyThread1 m = new MyThread1();

        Thread m1 = new MyThread1();

        //4.启动子线程
        m.start();
        m1.start();

        //5.在main方法里定义主线程
        for (int i = 0; i < 2; i++) {
            System.out.println("主线程" + i);
        }
    }
}

//1.创建子线程类继承Thread
class MyThread1 extends Thread{
    //2.重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 2; i++) {
            System.out.println("子线程" + i);
        }
    }
}
        方式一优缺点:
            优点:编码简单
            缺点:线程类已经继承Thread,无法继承其他类,不利于扩展。
    实现方式二:实现Runnable接口
        1.定义一个线程任务类MyRunnable实现Runnable接口,重写run方法
        2.创建MyRunnable任务对象
        3.把MyRunnable任务对象交给Thread处理
        4.调用线程对象start方法启动线程
        5.练习:
            public class Demo2 {
    public static void main(String[] args) {
        //第二种线程创建方式

        //3.创建一个任务对象
        Runnable r = new MyThread1();
        //4.把任务对象交给Thread处理
        Thread thread = new Thread(r);
        //5.启动线程
        thread.start();

        for (int i = 0; i < 2; i++) {
            System.out.println("主线程" + i);
        }
    }
}
//1.定义类实现Runnable接口
class MyThread01 implements  Runnable {
    //  2.重写run方法
    @Override
    public void run() {
        for (int i = 0; i <2; i++) {
            System.out.println("子线程" + i);
        }
    }
}
        方式二优缺点:
            优点:线程任务类只是实现接口,可以继续继承和实现接口,扩展性强。
            缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。(重写的run方法是没有返回值的)
        匿名内部类形式创建:
            1.创建Runnable的匿名内部类对象。
            2.交给Thread处理
            3.调用线程对象的start启动线程。
            练习:
                //匿名内部类形式一  (接口内部类)
        Runnable r1 = new Runnable() {
            @Override
            public void run() {

            }
        };
        Thread thread1 = new Thread(r1);
        thread1.start();
                    //匿名内部类形式二  (多态形式接口对象内部类)(常用)
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {

            }
        });
        t.start();
                         //匿名内部类形式三  (常用)
        new Thread(new Runnable() {
            @Override
            public void run() {

            }
        }).start();
                            //匿名内部类形式四
new Thread(() -> {
            for (int i = 0; i < 2; i++) {
                System.out.println("子线程" + i);
            }
        }).start();
    实现方式三:JDK5.0新增:实现Callable接口
        概念:
            1.前两种线程创建方式都存在一个问题:
* 重写的run方法均不能直接返回结果。
* 不适合需要返回线程执行结果的业务场景。

            2.怎么解决这个问题?
* JDK5.0提供了Callable和FutureTask来实现。
                1.得到任务对象:
                    1)定义类实现Callable接口,重写call方法,封装要做的事情。
                    2)用FutureTask把Callable对象封装成线程任务对象。
                2.把线程任务对象交给Thread处理。
                3.调用Thread的start方法启动线程,执行任务
                4.线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。
                练习: 

  /**
 * 目标:学会现成的创建方式三:实现Callable接口,结合FutureTask完成
 */
public class Test2_1 {
    public static void main(String[] args) {
        // 3.创建Callable任务对象(Callable对象无法直接交给Thread线程对象)
        Callable<String> call1 = new MyThread02(100);
        //Thread thread = new Thread(call); 错误代码 报错!
        /**
         * 4.把Callable任务对象交给FutureTask对象
         * 官方API显示:
         *            public class FutureTask<V> extends Object   implements RunnableFuture<V>
         *            public interface RunnableFuture<V>  extends Runnable, Future<V>
         *
         *  FutureTask对象的作用1:是Runnable的对象(实现了Runnable接口),可以交给Thread了;
         *  FutureTask对象的作用2:可以在线程执行完毕后通过调用其get方法得到线程执行完成的结果
         */
        FutureTask<String> f1 = new FutureTask<>(call1);

        //5.交给线程处理
        Thread thread1 =new Thread(f1);
        thread1.start();//第一个结果:子线程执行的结果是5050

        //6.可以接着创建第二个线程
        Callable<String> call2 = new MyThread02(200);
        FutureTask<String> f2 = new FutureTask<>(call2);
        Thread thread2 =new Thread(f2);
        thread2.start();//第二个结果:子线程执行的结果是20100

        //7.通过FutureTask(未来任务)获得结果
        try {
            String rs1 = f1.get();
            System.out.println("第一个结果:" + rs1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            String rs2 = f2.get();
            System.out.println("第二个结果:" + rs2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
 * 1.定义类实现Callable接口,重写call方法,封装要做的事情;
 * 申明线程任务执行完毕后的结果的数据类型
 */
class  MyThread02 implements Callable <String>{
    private  int n;

    public MyThread02(int n) {
        this.n = n;
    }

    //2.重写call方法(任务方法)
    @Override
    public String  call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= n; i++) {
            sum += i;
        }
        return "子线程执行的结果是" + sum;
    }
}


                方式三的优缺点:
                    优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
可以在线程执行完毕后去获取线程执行的结果。
                    缺点:编码复杂一点。
        Thread常用API说明
            Thread常用方法:
                  getName()
                    获取线程名称
                 setName()
                    设置线程名称
                 CurrentThread()
                    返回对当前正在执行的线程对象的引用 ;此方法是Thread类的静态方法,可以直接使用Thread类调用;这个当法是在哪个线程执行中调用的就会得到哪个线程对象。
                 setPriority()  
                    线程优先级设置(线程默认优先级为5) ; 可设置1~10;只会增加优先的概率,并不一定会优先执行
                synchronized (Object.class)
 synchronized (this)
                    设置线程锁  线程是随机抢占的,加锁后率先抢到的这个线程会执行完毕再自动释放锁供其他线程进行抢占。 
                setDaemon(Boolean)
                    守护线程   以QQ为例,当主程序关闭的时候,聊天窗口也随之关闭,这个聊天窗口的线程就是被守护的线程。
                start()
                    线程启动方法
            Thread的构造器
                public Thread(String  name)
                    可以为当前线程指定名称
                public Thread(Runnable target)
                    封装Runnable对象成为线程对象
                public Thread(Runnable target,String name)
                    封装成Runnable对象成为线程对象,并指定线程名称。
            Thread类的线程休眠方法
                public  static void sleep(Long time)
                    让当前线程休眠指定的时间后再继续执行,单位为毫秒。
        线程安全
            同步思想概述:
                线程安全问题是什么、发生的原因:
                    线程安全问题:
                        多个线程同时操作同一个资源的时候可能会出现业务安全问题,称为线程安全问题。
                    线程安全问题出现的原因:
                        存在多线程并发,同时访问共享资源,存在修改共享资源。
                如何保证线程安全?
                    让多个线程实现先后依次访问共享资源。
            方式一:同步代码块
                线程同步的核心思想:
                    加锁;把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,其他线程才能进来。
                     synchronized (同步锁对象){
        操作共享资源的代码(核心代码)
}

锁对象要求:
理论上:锁对象只要对于当前同时执行的线程来说是同个对象即可。
                线程同步:
                    锁对象用任意唯一的对象好不好?
                        不好,会影响其他无关线程的执行。
                    锁对象的规范要求:
                        规范上:建议使用共享资源作为锁对象。
                        对于实例方法建议使用this作为锁对象。
                        对于静态方法建议使用字节码(类名.class)对象作为锁对象。
                    总结:同步代码块是如何实现线程安全的?
                        对出现问题的核心代码使用synchronized进行加锁。
                        每次只能一个线程占锁进入访问。
            线程安全问题案例模拟:

                /**
 *  线程安全案例:取钱业务
 *     小明和小红是一对夫妻,他们有一个共同的账户,余额是10万元,模拟两人同时去取钱10万元。
 *      分析:1.需要提供一个账户类,创建一个账户对象代表2人的共享账户。
 *          2.需要定义一个线程类,线程类可以处理账户对象。
 *          3.创建两个线程对象,传入同一个账户对象。
 *          4.启动2个线程,去同一个账户对象中取钱10万
 */
public class Test11 {
    public static void main(String[] args) {
        //1.定义线程类  创建共享账户对象
      Account acc = new Account("ICBU-111",100000);
      DrawThread dt = new DrawThread(acc);
        //2.创建2个线程对象 代表小明和小红同时进来了。
      Thread thread1 = new Thread(dt,"小明");
      Thread thread2 = new Thread(dt,"小红");

        thread1.start();
        thread2.start();
    }
}

//账户类
class Account{
    private  double money;//账户余额
    private  String cardId;

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public Account(){

    }
    public Account( String cardId,double money) {
        this.money = money;
        this.cardId = cardId;
    }
    public void drawMoney(double money){
        //拿到是谁来取钱
        String name  = Thread.currentThread().getName();
        //判断余额是否足够
        synchronized (Object.class) {
            if (this.money >= money){
                //钱够了
                System.out.println(name + "来取钱成功,吐出"+ money);
                //更新余额
                this.money  -= money;
                System.out.println(name+"取钱后余额剩余" + this.money);
            }else {
                //钱不够
                System.out.println(name + "来取钱,余额不足");
            }
        }
    }
}
//取钱线程
class  DrawThread implements  Runnable{
    //接收处理的账户对象
    private  Account acc;
    public DrawThread(Account acc){
        this.acc = acc;
    }
    @Override
    public void run() {
        //小明、小红 同时取钱
        acc.drawMoney(100000);
    }
}
/**
 *  加锁前代码测试结果:
 *          小红来取钱成功,吐出100000.0
 *          小明来取钱成功,吐出100000.0
 *          小红取钱后余额剩余0.0
 *          小明取钱后余额剩余-100000.0
 *
 *  加锁后代码测试结果:
 *          小明来取钱成功,吐出100000.0
 *          小明取钱后余额剩余0.0
 *          小红来取钱,余额不足
 */


            方式二:同步方法
                同步方法的底层原理:
                    同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
                    如果方法是实例方法:同步方法默认用this作为的锁对象。但是代码要高度面向对象!
                    如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
                同步代码块好还是同步方法好一点?
                    同步代码块锁的范围更小,同步方法锁的范围更大。性能上同步代码块锁有优势;实际开发中可能同步方法锁用的比较多一些,可读性好,写法方便。
            方式三:Lock锁
                Lock概念:
                    * 为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,更加灵活、方便。
                    * Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。
                    * Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象。
                方法:
                    public ReentrantLock()    获得Lock锁的实现类对象
                    private  final Lock lock = new ReentrantLock();
      lock.lock();
      lock.unlock();
                Lock的API
                    void lock   获得锁
                    void unlock  释放锁
    线程通信(了解)
        什么是线程通讯、如何实现?
            所谓线程通讯就是线程间相互发送数据。
        线程通信常见形式:
            通过共享一个数据的方式实现。
            根据共享数据的情况决定自己该怎么做,以及通知其他线程怎么做。
        线程通信实际应用模型
            生产者与消费者模型:生产者线程负责生产数据,消费者线程负责消费生产者产生的数据。
            一般要求:生产者线程生产完数据后唤醒消费者,然后等待自己,消费者消费完该数据后唤醒生产者,然后等待自己。
        Object类的等待和唤醒方法:
            void wait()  当前线程等待,直到同一个对象的另一个线程调用notify()方法或者notifyAll()方法唤醒自己。 
            void notify()
                唤醒正在等待对象监视器(锁对象)的单个线程
            void notifyAll()
                唤醒正在等待对象监视器(锁对象)的所有线程
            注意⚠️: 上述方法应该使用当前同步锁对象进行调用。
        线程通信案例1
             /**
 * 线程通信案例模拟:
 *      模拟手机接电话系统,有电话就接听,没电话就等待。
 *      线程通讯的前提:线程通讯通常是在多个线程操作同一个共享资源的时候,
 *      需要进行通讯,且要保证线程安全。
 */

public class Phone {
    //实现线程之间通信:默认认为手机当前处于等待来电提醒
    private boolean flag = false;

    public void run(){
        //a 负责来电提醒的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (Object.class){
                    try {
                        while (true){
                            synchronized (Phone.this){
                                if (!flag){
                                    //代表要来电提醒了
                                    System.out.println("您好,有新的来电,请接听");
                                    flag = true;

                                    Phone.this.notify();
                                    Phone.this.wait();
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        //b 接电话线程 正式接听
        new Thread(new Runnable() {
            @Override
            public void run() {
                    //不断的接听电话
                try {
                    while(true){
                        synchronized (Phone.this){
                        if (flag){
                            //可以接听电话了
                            System.out.println("电话接通中,通信5分钟结束了~~");
                            Thread.sleep(3000);
                            flag =false;//代表要继续等待呼入电话
                            //唤醒别人   等待自己
                            Phone.this.notify();
                            Phone.this.wait();
                        }
                    }
                }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    public static void main(String[] args) {
        //1.创建一部手机对象
        Phone huawei = new Phone();
         huawei.run();
    }
}


        线程通信案例2
        

     public class Demo1 {
    public static void main(String[] args) {
        Goods goods = new Goods("保时捷",66.6,false);//true代表需要被生产
        Customer customer = new Customer(goods);
        Producer producer = new Producer(goods);
        //哪个线程先抢到合适?设置让消费者先抢
        new Thread(customer).start();
        new Thread(producer).start();
    }
}

//商品类 共享资源
class Goods {
    private String name;//商品名字
    private double price;//商品价格
    private  boolean  shouldProduct;//是否生产  设定若没有商品为true,需要生产
    public Goods(){} //无参构造

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public boolean isShouldProduct() {
        return shouldProduct;
    }

    public void setShouldProduct(boolean shouldProduct) {
        this.shouldProduct = shouldProduct;
    }

    //toString方法 打印对象是能看懂的字符串,不写的话打印的是内存地址
    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", shouldProduct=" + shouldProduct +
                '}';
    }

    public Goods(String name, double price, boolean shouldProduct) {
        this.name = name;
        this.price = price;
        this.shouldProduct = shouldProduct;
    }
}

//消费者线程
class Customer implements Runnable{
    //由于两个线程需要共享一个资源,商品资源需要实例化给线程
    private  Goods goods;
    public Customer(Goods goods){
        this.goods = goods;
    }

    @Override
    public void run() {
        //消费多个 无限制循环
        while(true){
            synchronized (goods){
                //Goods类的属性shouldProduct为false就不需要生产
                if (!goods.isShouldProduct()){
                    //  执行的不需要生产的代码 直接购买
                    System.out.println("消费者购买了:" + goods.getName()+",价格为:" + goods.getPrice());
                    //购买完这个商品就没了 需要生产 重新标记为true
                    goods.setShouldProduct(true);
                    //唤醒生产者
                    goods.notify();
                }else {
                    //需要生产的代码,消费者进入到等待状态
                    try {
                        goods.wait();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

//生产者线程
class Producer implements Runnable{
    private  Goods goods;
    public Producer(Goods goods){
        this.goods = goods;
    }

    @Override
    public void run() {
        //设置变量 变量为偶数生产奥迪,奇数生产特斯拉
        int count = 0;
        while (true){
            try {
                //让生产者线程睡一会
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (goods){
                //需要生产
                if(goods.isShouldProduct()){
                    if (count % 2 == 0){
                        goods.setName("奥迪Rs8");
                        goods.setPrice(54.3);
                    }else {
                        goods.setName("特斯拉");
                        goods.setPrice(23.6);
                    }
                    //生产完以后标记shouldProduct为false
                    goods.setShouldProduct(false);
                    System.out.println("生产者生产了:" + goods.getName() + ",价格为:" + goods.getPrice());
                    count++;
                    //已经生产好了  唤醒消费者
                    goods.notify();
                }else {
                    //有车 不需要生产  生产者等待
                    try {
                        goods.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
/**
 * 运行结果:
 *      消费者购买了:保时捷,价格为:66.6
 *      生产者生产了:奥迪Rs8,价格为:54.3
 *      消费者购买了:奥迪Rs8,价格为:54.3
 *      生产者生产了:特斯拉,价格为:23.6
 *      消费者购买了:特斯拉,价格为:23.6
 *      生产者生产了:奥迪Rs8,价格为:54.3
 *      消费者购买了:奥迪Rs8,价格为:54.3
 *      生产者生产了:特斯拉,价格为:23.6
 *      消费者购买了:特斯拉,价格为:23.6
 */


    线程的生命周期
        线程的状态
            线程的状态:也就是线程从生到死的过程,以及中间经历的各种状态及状态转换。
            java一共定义了6种状态
6种状态都定义在了Thread类的内部枚举类中,线程在运行过程中,6种状态会随着代码互相转换。
                public enum State {
 
        NEW,   //新建状态

        
        RUNNABLE,     // 可运行状态

        
        BLOCKED,    // 被终止| 阻塞状态

       
        WAITING,     //无限等待状态|等待唤醒状态

       
        TIMED_WAITING,      //计时等待,例如休眠状态

    
        TERMINATED;    //被终止|死亡状态
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你需要在Java中使用多线程进行IO操作,可以使用Java的线程池和Java NIO(New IO)库。以下是一个使用线程池和NIO库进行文件导出的示例代码: ```java import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Exporter { public static void main(String[] args) { // 创建线程池 ExecutorService pool = Executors.newFixedThreadPool(10); // 定义文件路径和文件名 final String filePath = "/path/to/file"; final String fileName = "file.txt"; // 为每个线程分配写入文件的位置 final int blockSize = 1024 * 1024; // 1MB final long fileSize = 1024 * 1024 * 1024; // 1GB int blockCount = (int) (fileSize / blockSize); for (int i = 0; i < blockCount; i++) { final int blockIndex = i; pool.execute(new Runnable() { @Override public void run() { try { // 创建文件通道 RandomAccessFile file = new RandomAccessFile(filePath + fileName, "rw"); FileChannel channel = file.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(blockSize); // 写入数据 long position = blockIndex * blockSize; for (int j = 0; j < blockSize; j++) { buffer.put((byte) (position + j)); } buffer.flip(); channel.write(buffer, position); // 关闭文件通道 channel.close(); file.close(); } catch (IOException e) { e.printStackTrace(); } } }); } // 关闭线程池 pool.shutdown(); } } ``` 在上述代码中,我们使用了一个线程池来管理多个线程,每个线程负责写入文件的一个固定大小的块。我们使用NIO库来读写文件,这样可以提高IO性能。请注意,我们使用的是随机访问文件(RandomAccessFile),这使得我们可以在文件中定位并写入特定位置的字节。在实际应用中,你需要根据实际需求来调整块的大小和线程数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值