hierynomus / smbj

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

File is not getting written when using underlying OutputStream #628

Closed Eugeniu-N closed 3 years ago

Eugeniu-N commented 3 years ago

Code using OutputStream:

Set<AccessMask> accessMasks = EnumSet.of(AccessMask.GENERIC_WRITE);
Set<SMB2ShareAccess> shareAccesses = EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE);
try (File fileToWrite = share.openFile(fileName, accessMasks, null, shareAccesses, SMB2CreateDisposition.FILE_OVERWRITE_IF, null)){
    fileToWrite.getOutputStream().write(data);
    fileToWrite.getOutputStream().flush();
}

No data is written to the file, files are created but they are empty. Whereas File's write method writes the data correctly:

Set<AccessMask> accessMasks = EnumSet.of(AccessMask.GENERIC_WRITE);
Set<SMB2ShareAccess> shareAccesses = EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE);
try (File fileToWrite = share.openFile(fileName, accessMasks, null, shareAccesses, SMB2CreateDisposition.FILE_OVERWRITE_IF, null)){
    int writtenBytes = 0;
    int currentWritten = 0;
    while (writtenBytes != data.length) {
            currentWritten = fileToWrite.write(data, writtenBytes, writtenBytes, data.length - writtenBytes);
        writtenBytes = writtenBytes + currentWritten;
    }
}
neoxpert commented 3 years ago

By calling .getOutputStream() a new OutputStream is created with every call. The OutputStream is not set to append data but overwrite. You should only create it once and perform your desired actions like:

Set<AccessMask> accessMasks = EnumSet.of(AccessMask.GENERIC_WRITE);
Set<SMB2ShareAccess> shareAccesses = EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE);
try (File fileToWrite = share.openFile(fileName, accessMasks, null, shareAccesses, SMB2CreateDisposition.FILE_OVERWRITE_IF, null);
     OutputStream out = file.getOutputStream())
{
    out.write(data);
    out.flush();
}
hierynomus commented 3 years ago

@Eugeniu-N Did the answer from @neoxpert help you? If so, please close this issue, or update it.

Eugeniu-N commented 3 years ago

Yes, flushing the exact same OutputStream instance of .getOuputStream() worked