Assim, a partir do rastreamento de pilha, podemos ver que quando o objeto FileOutputStream está sendo criado, dentro desse código, ele faz uma chamada para open () que falha e lança uma FileNotFoundException com o erro "Sem espaço no dispositivo" mensagem.
É interessante ver o código que está falhando (FileOutputStream.java):
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
this.fd = new FileDescriptor();
this.append = append;
fd.incrementAndGetUseCount();
open(name, append); /* HERE */
}
Portanto, esta é uma chamada para o código nativo (FileOutputStream_md.c):
Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
jstring path, jboolean append) {
fileOpen(env, this, path, fos_fd,
O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
}
E fileOpen (io_util_md.c):
fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
{
WITH_PLATFORM_STRING(env, path, ps) {
FD fd;
#ifdef __linux__
/* Remove trailing slashes, since the kernel won't */
char *p = (char *)ps + strlen(ps) - 1;
while ((p > ps) && (*p == '/'))
*p-- = 'JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode))
JVMWrapper2("JVM_Open (%s)", fname);
//%note jvm_r6
int result = os::open(fname, flags, mode);
if (result >= 0) {
return result;
} else {
switch(errno) {
case EEXIST:
return JVM_EEXIST; /* returns -100, will trigger Exception */
default:
return -1; /* returns -1, will trigger Exception */
}
}
JVM_END
';
#endif
fd = JVM_Open(ps, flags, 0666); /* HERE IS WHERE THINGS BREAK */
if (fd >= 0) {
SET_FD(this, fd, fid);
} else {
throwFileNotFoundException(env, path); /* EXCEPTION */
}
} END_PLATFORM_STRING(env, ps);
}
E JVM_Open (jvm.cpp):
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
this.fd = new FileDescriptor();
this.append = append;
fd.incrementAndGetUseCount();
open(name, append); /* HERE */
}
E os :: open é apenas um wrapper em torno fdopen (2) syscall.
Você pode reproduzir esse erro sempre que quiser? Em caso afirmativo, execute o comando com strace -e trace=fopen,fdopen,freopen
e publique os resultados (ou anexe ao processo em execução com strace -p <PID>
).