hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
707 stars 180 forks source link

File getting truncated to 0 bytes after overwrite get timeout exception #778

Open msayed96 opened 1 year ago

msayed96 commented 1 year ago

Hi, I'm trying to overwrite file using this code:

try(File smbFile = this.getShare().openFile(getPathWithoutShareName(path) + fileName,
                EnumSet.of(AccessMask.FILE_READ_DATA, AccessMask.FILE_EXECUTE, AccessMask.FILE_WRITE_DATA),
                EnumSet.of(FILE_ATTRIBUTE_NORMAL),
                ALL,
                FILE_OVERWRITE,
                EnumSet.of(SMB2CreateOptions.FILE_DIRECTORY_FILE))) {
            try (OutputStream os = smbFile.getOutputStream(); FileInputStream fileInputStream = new FileInputStream(file)) {
                os.write(IOUtils.toByteArray(fileInputStream));
            }
        }

The issue happens when an exception thrown during the write process, i got: com.hierynomus.smbj.common.SMBRuntimeException: com.hierynomus.protocol.transport.TransportException: java.util.concurrent.ExecutionException: com.hierynomus.smbj.common.SMBRuntimeException: java.util.concurrent.TimeoutException: Timeout expired

and then the original file got corrupted and changed to 0 bytes, so it seems like the write is not resilient. any suggestions how to handle this? i don't want to lose the original file in case of failures.

hierynomus commented 1 year ago

@msayed96 If you purposefully open the file for an overwrite operation, it will indeed be truncated by the server before starting the write. You're better off writing to a temporary file, and then renaming the file to the correct name after the write has been succesful. There is no bug here in the code.

msayed96 commented 1 year ago

@hierynomus the only issue with this approach is that you are actually uploading a completely new file (with new fileId), so in case you would like to just overwrite the original file, you will end up having a new file, although with the same name.

hierynomus commented 1 year ago

Yes, but that's the only fail-safe way of overriding a completely uploaded file vs writing a corrupted one.