asLody/VirtualApp · warning · IOException
Couldn't append
Error message
Couldn't append
What it means
AtomicFile.truncate() opens the base file for output to zero it out. On FileNotFoundException it throws IOException 'Couldn't append <path>' (message wording is misleading — this is an open/create failure, not append). The generic IOException from sync/close is swallowed.
Solutions
- Ensure the file's parent directory and file exist (call startWrite/newFile once) before truncate
- Check write permission/storage state for the base path
- Wrap truncate in try-catch and recreate the AtomicFile from a valid directory
Example fix
// before atomicFile.truncate(); // FileNotFoundException if file/dir missing // after File parent = base.getParentFile(); if (!parent.exists()) parent.mkdirs(); if (!base.exists()) base.createNewFile(); atomicFile.truncate();
Defensive patterns
Strategy: validation
Validate before calling
File base = ...;
if (!base.exists()) {
base.getParentFile().mkdirs();
base.createNewFile();
} Try / catch
try {
atomicFile.truncate();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Couldn't append")) {
// file missing: recreate via startWrite before truncating
}
} Prevention
- Never truncate an AtomicFile before its first startWrite
- Avoid the deprecated truncate/openAppend APIs
- Check base path existence and writability first
When it happens
Trigger: Calling truncate() when mBaseName cannot be opened for writing: parent directory missing, storage read-only, or the file path is not writable by the app uid.
Common situations: Truncating before any startWrite ever created the file/directory; sdcard unmounted; path moved after refactor.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Couldn't create directory
- Couldn't create
- Unable to create application
- Unable to start receiver
- VirtualCore.startup() must called in main thread.
AI-assisted analysis of asLody/VirtualApp@666fefcb5d (2026-09-09).
Data as JSON: /api/errors/1378d1ee2d70f577.
Report an issue: GitHub.
Appendix: source
Thrown at VirtualApp/lib/src/main/java/com/lody/virtual/helper/utils/AtomicFile.java:196
System.arraycopy(data, 0, newData, 0, pos);
data = newData;
}
}
} finally {
stream.close();
}
}
/**
* @deprecated This is not safe.
*/
public void truncate() throws IOException {
try {
FileOutputStream fos = new FileOutputStream(mBaseName);
fos.getFD().sync();
fos.close();
} catch (FileNotFoundException e) {
throw new IOException("Couldn't append " + mBaseName);
} catch (IOException e) {
}
}
/**
* @deprecated This is not safe.
*/
@Deprecated public FileOutputStream openAppend() throws IOException {
try {
return new FileOutputStream(mBaseName, true);
} catch (FileNotFoundException e) {
throw new IOException("Couldn't append " + mBaseName);
}
}
static boolean sync(FileOutputStream stream) {
try {
if (stream != null) {View on GitHub (pinned to 666fefcb5d)