Reputation: 9384
I am trying to read files from an SMB share using the smbj library. My code needs to read into a byte array (see below), and I need to know the file size before reading. Unfortunately when studying the code I can only find methods to get the allocated size, which usually is bigger than the real file size.
So how can I get the actual size of the file in bytes?
My (wrong code) so far looks like this:
SMBClient client = new SMBClient();
try(Connection connection = client.connect(hostname)) {
AuthenticationContext ac = new AuthenticationContext(user, password.toCharArray(), domain);
Session session = connection.authenticate(ac);
// Connect to Share
try (DiskShare share = (DiskShare) session.connectShare(shareName)) {
FileAllInformation fileInfo = share.getFileInformation(path);
File file = share.openFile(path, EnumSet.of(AccessMask.GENERIC_READ), null, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null);
long fileSize = fileInfo.getStandardInformation().getAllocationSize();
// this part is problematic as it throws an IOException
// if not the fileSize amount of bytes can be read
byte[] bytes = IOUtils.toByteArray(fileIn, fileInfo.getStandardInformation().getAllocationSize());
}
}
Why read files into a byte array?
I am writing a protocol plugin for Apache Nutch. And the API expects file content to be provided as byte[].
Why not have IOUtils read the complete file?
The call IOUtils.toByteArray(fileIn)
would read the complete file. But it fails with an IOException if the file is bigger than 2 GB. So I'd like to specify the maximum size to read. And here the IOUtils API allows to specify the amount of bytes using IOUtils.toByteArray(fileIn, amount)
. But the caveat is that now the call will fail if the file is smaller. Thus I need to know the filesize (and thus the amount of bytes I want to read) before making that call.
Upvotes: 1
Views: 155
Reputation: 2012
Looking at their github repo, the remoteCopyTo()
function uses this:
long fileSize = getFileInformation(FileStandardInformation.class).getEndOfFile();
So, in your case, you want to try the following:
long fileSize = fileInfo.getStandardInformation().getEndOfFile();
I believe this will give you the actual size.
Upvotes: 2
Reputation: 3390
Why bother with the length? Can't you just use
byte[] IOUtils.toByteArray(InputStream inputStream)
and let that utility read until the End of File is reached?
Upvotes: 0