目前在一个接收文件的demo遇到的问题,在多线程方法内:
FileOutputStream fos = null;if (writeNum == 1) { // 第一次接收
  firstFosWrite(file, byte[], fos);
}else{
  fosWrite(byte[], fos);
} private void firstFosWrite(File file, byte[] bytes, FileOutputStream fos) throws IOException {
        System.out.println("**************第一次写文件*******************bytes" + bytes.length);
//        file = new File(filePath);
        fos = new FileOutputStream(file);
        fos.write(bytes);
        fos.flush();
    }private synchronized void fosWrite(byte[] bytes, FileOutputStream fos) throws IOException {
        System.out.println("**************写文件*******************bytes" + bytes.length);
        fos.write(bytes, 0, bytes.length);
        fos.flush();
    }然而,在具体的使用过程中遇到了问题:firstFosWrite方法正常,fosWrite方法fos为空指针,请教大佬答疑。。另外,思考了其他方式,比如将FileOutputStream fos作为全局静态变量,但是这是在多线程内,这样做法是线程不安全的,只能保证单线程上传不出错,两个线程一起调用,文件数据就杂糅了

解决方案 »

  1.   

    firstFosWrite 方法里的 fos = new FileOutputStream(file); 作用域,只在此方法内。
    可以 firstFosWrite 返回类型改成 FileOutputStream , 主方法里: fos = firstFosWrite(...);
      

  2.   

    如LS说,作用域不同,要么如LS说的,要么FileOutputStream fos = null;改为成员变量,方法不用fos参数
    另外,多线程,firstFosWrite和writeNum估计也要加锁(不知道writeNum是不是成员变量,在哪里由哪个线程赋值)
      

  3.   

    上面的回答可能没有回答到点子上,你的意思我大概看明白了,你是想我第一次已经初始化过了,当第二次或更大次数时为什么fos依然是空的呢?
    首先你没有理解java的内存模型,画一张图给你把能看明白吗,你firstFosWrite方法的形参fos其实是重新在栈上开了一个引用(存储于虚拟机栈,线程安全的),两个开始都是null,然后你对后面一个赋值了,之前那个还是null,向下面这种最简单的代码,你试一下看看
    public static void main(String[] args) {
    int i =7;
    System.out.println(i);
    }

    public static void tt(int i) {
    i = 9;
    }
    改成这样就可以了
    if (writeNum == 1) { // 第一次接收
    fos = new FileOutputStream(file);
      firstFosWrite(file, byte[], fos);
    }else{
      fosWrite(byte[], fos);

    多线程情况下直接到方法里去初始化,刚才也说过了,方法里的局部变量表是线程安全的,不需要两个方法,就一个方法就行了
    private void fosWrite(File file, byte[] bytes) throws IOException {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes);
            fos.flush();
        }
      

  4.   

    你好,业务场景是这样的,两个write方法中的byte[]只是文件中的一部分,理想中的实现是,收到一部分byte[]就写入到文件中,文件只会越写越大,如果每次都初始化,这样操作是不是会导致文件始终只有最后写入的那一小部分?
      

  5.   

    你好,业务场景是这样的,两个write方法中的byte[]只是文件中的一部分,理想中的实现是,收到一部分byte[]就写入到文件中,文件只会越写越大,如果每次都初始化,这样操作是不是会导致文件始终只有最后写入的那一小部分?
    每次初始化写也没问题啊,FileOutputStream fos = new FileOutputStream(file, true);用这个构造函数,是追加写的
      

  6.   

    我觉得应该把IO变量和IO方法单独建一个类,然后线程构造引入IO类比较好,及不会发生上述情况,也方便方法同步加锁。
      

  7.   

    你好,业务场景是这样的,两个write方法中的byte[]只是文件中的一部分,理想中的实现是,收到一部分byte[]就写入到文件中,文件只会越写越大,如果每次都初始化,这样操作是不是会导致文件始终只有最后写入的那一小部分?
    每次初始化写也没问题啊,FileOutputStream fos = new FileOutputStream(file, true);用这个构造函数,是追加写的感谢答疑,已经解决了我的问题