目前在一个接收文件的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作为全局静态变量,但是这是在多线程内,这样做法是线程不安全的,只能保证单线程上传不出错,两个线程一起调用,文件数据就杂糅了
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作为全局静态变量,但是这是在多线程内,这样做法是线程不安全的,只能保证单线程上传不出错,两个线程一起调用,文件数据就杂糅了
可以 firstFosWrite 返回类型改成 FileOutputStream , 主方法里: fos = firstFosWrite(...);
另外,多线程,firstFosWrite和writeNum估计也要加锁(不知道writeNum是不是成员变量,在哪里由哪个线程赋值)
首先你没有理解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();
}
每次初始化写也没问题啊,FileOutputStream fos = new FileOutputStream(file, true);用这个构造函数,是追加写的
每次初始化写也没问题啊,FileOutputStream fos = new FileOutputStream(file, true);用这个构造函数,是追加写的感谢答疑,已经解决了我的问题