AgNO3 / jcifs-ng

A cleaned-up and improved version of the jCIFS library
GNU Lesser General Public License v2.1
314 stars 104 forks source link

Problem reading files like pdf and png #279

Closed CarstenJensenATP closed 3 years ago

CarstenJensenATP commented 3 years ago

Hi Thank you for creating this project.

I have a problem reading files like pdf and png.

In the following example a pdf file is used: 2020-Scrum-Guide-US.pdf – a random pdf file found on scrumguides.org (https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-US.pdf)

I read it from my downloads using java.nio and writes it to a Windows fileshare (win2016) using an SmbFile. This works fine. When I compare the two copies using Notepad++ they are identical. Then I read the two copies using java.nio and an SmbFile into byte[] and compare them (see method below). The two arrays have the same length (254353) but a difference is found at index 194808 In debug mode, I can see that the SmbFileInputStream fp property has the value 194808 when it finishes! Here are the loggings (SmbFileFactory Is my own class for creating SmbFile instances with cifs context) 2021-04-28 14:18:31 DEBUG SmbFileFactory:61 - cifs context created for user ntatp;batbat01 2021-04-28 14:18:43 TRACE SmbFileInputStream:311 - read: fid=FileHandle \prta\jcifs2\targetfile4 [fid=FE3B0300500000000900000050000000,tree=1,flags=0,access=1,attrs=0,options=0],off=0,len=254353 2021-04-28 14:18:43 TRACE SmbFileInputStream:323 - read: len=254353,r=64936,fp=0,b.length=254353 2021-04-28 14:18:43 TRACE SmbFileInputStream:323 - read: len=189417,r=64936,fp=64936,b.length=254353 2021-04-28 14:18:43 TRACE SmbFileInputStream:323 - read: len=124481,r=64936,fp=129872,b.length=254353 Difference in element 194808 data1:-47 data2:0 index:194808 data1:-127 data2:0 index:194809 (etc.).

It seam like it stops after 3 times reading 64936 bytes = 194808, but no errors is reported.

My compare method static boolean compareLocalFileToShareFile(File source1, SmbFile source2) throws IOException { byte[] data1 = Files.readAllBytes(Paths.get(source1.getAbsolutePath())); byte[] data2 = new byte[(int)source2.length()]; InputStream is = source2.getInputStream(); is.read(data2); is.close(); if (Arrays.equals(data1,data2)) return true; for (int i=0;i<data1.length;i++) { if (data1[i] != data2[i]) { System.out.println("Difference in element " + i); for (int j=i;j<i+100 && j<data1.length;j++) { System.out.println("data1:"+data1[j]+" data2:"+data2[j]+" index:"+j); } break; } } return false; }

my jcifs properties jcifs.smb.client.dfs.disabled=true jcifs.smb.client.responseTimeout=120000 jcifs.smb.client.soTimeout=140000 jcifs.smb.client.ignoreCopyToException=false jcifs.smb.client.minVersion=SMB202

It works fine with smaller properties and xml files. And it works fine with jcifs 1.3.18

I hope you can help. Thanks 😊

mbechler commented 3 years ago

is.read(data2); in conformance with the InputStream specification will not read the full buffer, but only up to it's size. jcifs originally did implement a "readFully" style operation but this is pretty bad (as you would have to properly align this with the smb buffer size to get good performance). So you will have to implement a loop and track your progess until reach the end.

CarstenJensenATP commented 3 years ago

Hi Moritz Thanks for your response. I've looked at the code in ReadWriteTest.verifyRandom and implemented a similar loop, and it works.