hierynomus / smbj

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

how to find only directories(not files) inside a folder #738

Closed satya081 closed 1 year ago

satya081 commented 1 year ago

i have a way to find all files presents inside a folder but unable to find all the folders present inside a folders Could you please help me

kemcon commented 1 year ago

This is for finding files, but changing from == 0 to >0 should do it:

        try (DiskShare share = (DiskShare) smbClientSession.connectShare(location)) {
            List<Filenames> list = new ArrayList<>();
            for (FileIdBothDirectoryInformation f : share.list("/", "*")) {
                if ((f.getFileAttributes() & FileAttributes.FILE_ATTRIBUTE_DIRECTORY.getValue()) == 0) {
                    list.add(new Filenames(f.getFileName(), f.getFileName()));
                }
            }
satya081 commented 1 year ago

@kemcon this code detects xml file as directory as well. I added the exact code given by you and I am getting below error. ocom.hierynomus.mssmb2.SMBApiException: STATUS_NOT_A_DIRECTORY (0xc0000103): Create failed for \testing.abc.eul.int\C\test\download\Files\generated\content.xml at com.hierynomus.smbj.share.Share.receive(Share.java:380) at com.hierynomus.smbj.share.Share.sendReceive(Share.java:359) at com.hierynomus.smbj.share.Share.createFile(Share.java:156) at com.hierynomus.smbj.share.DiskShare.createFileAndResolve(DiskShare.java:75) at com.hierynomus.smbj.share.DiskShare.access$100(DiskShare.java:55) at com.hierynomus.smbj.share.DiskShare$2.apply(DiskShare.java:109) at com.hierynomus.smbj.share.DiskShare$2.apply(DiskShare.java:105) at com.hierynomus.smbj.paths.PathResolver$1.resolve(PathResolver.java:32) at com.hierynomus.smbj.paths.SymlinkPathResolver.resolve(SymlinkPathResolver.java:62) at com.hierynomus.smbj.share.DiskShare.resolveAndCreateFile(DiskShare.java:105) at com.hierynomus.smbj.share.DiskShare.open(DiskShare.java:65) at com.hierynomus.smbj.share.DiskShare.openDirectory(DiskShare.java:151) at com.hierynomus.smbj.share.DiskShare.list(DiskShare.java:258) at com.hierynomus.smbj.share.DiskShare.list(DiskShare.java:231) at com.hierynomus.smbj.share.DiskShare.rmdir(DiskShare.java:383) at europa.edit.util.E2eUtil.deleteFilesFoldersFromRemoteMachine(E2eUtil.java:622)

my code

                      for (FileIdBothDirectoryInformation f : share.list(relativePath)) {
                            if (!(".".equals(f.getFileName()) || "..".equals(f.getFileName()))) {
                                if ((f.getFileAttributes() & FileAttributes.FILE_ATTRIBUTE_DIRECTORY.getValue()) == 0) {
                                    folderLocationPath.add(relativePath + Constants.FILE_SEPARATOR + f.getFileName());
                                } else {
                                    fileLocationPath.add(relativePath + Constants.FILE_SEPARATOR + f.getFileName());
                                }
                            }
                        }
                        for (String path : folderLocationPath) {
                            try {
                                share.rmdir(path, true);// line number 622 from E2eUtil.java
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        for (String path : fileLocationPath) {
                            try {
                                share.rm(path);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

My requirement is to identify folders and files and put them in different list and iterate both list and remove directory or remove files accordingly.

after raising this issue in github, i tried and found below solution which is working perfectly fine for directories.

                    for (FileIdBothDirectoryInformation f : share.list(relativePath)) {
                            if (!(".".equals(f.getFileName()) || "..".equals(f.getFileName()))) {
                                if (EnumWithValue.EnumUtils.isSet(f.getFileAttributes(), FileAttributes.FILE_ATTRIBUTE_DIRECTORY)) {
                                    folderLocationPath.add(relativePath + Constants.FILE_SEPARATOR + f.getFileName());
                                } else {
                                    fileLocationPath.add(relativePath + Constants.FILE_SEPARATOR + f.getFileName());
                                }
                            }
                        }

only difference i found between your code and my code is below. my code - EnumWithValue.EnumUtils.isSet(f.getFileAttributes(), FileAttributes.FILE_ATTRIBUTE_DIRECTORY) your code - f.getFileAttributes() & FileAttributes.FILE_ATTRIBUTE_DIRECTORY.getValue()) == 0

hierynomus commented 1 year ago

@satya081 Are you just copy pasting, or also understanding the code... The ==0 check checks whether the specific FileAttribute is not part of the attributes of the FileIdBothDirectoryInformation. If you actually use the EnumUtils.isSet check it checks whether it is part of the attributes.

satya081 commented 1 year ago

Really sorry. I just saw the piece of code but missed the writings from @kemcon. code given by @kemcon is perfectly working. Thank you so much. :)