可观察RXJava的smb文件更改通知

时间:2019-02-11 11:28:35

标签: observable smbj

我需要监视文件夹中的文件更改。 我使用smb连接到远程文件夹,并且找到了一个很好的示例。

尽管此示例使用了while(true)循环和被阻塞的future.get

我想知道它是否可以在可观察范围内工作,因此可以将其放在后台线程中。 我尝试了一些方法,因为它不起作用

这是原始代码-工作但受阻

 /**
 * Notify when a smbFile is changed in the directory
 */
public static void smbjWatch() throws Exception {

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);


    SmbConfig config = SmbConfig.builder()
            .withMultiProtocolNegotiate(true)
            .withDfsEnabled(true)
            .withNegotiatedBufferSize()
            .withTimeout(120, TimeUnit.SECONDS) // Timeout sets Read, Write, and Transact timeouts (default is 60 seconds)
            .withSoTimeout(180, TimeUnit.SECONDS) // Socket Timeout (default is 0 seconds, blocks forever)
            .build();

    SMBClient smbClient = new SMBClient(config);
    Connection connection = null;
    try {
        connection =  smbClient.connect(ApplicationCore.hardwareNetworkIp);
    } catch (IOException e) {
        e.printStackTrace();
    }

    AuthenticationContext ac = new AuthenticationContext(ApplicationCore.hardwareNetworkLogin, ApplicationCore.hardwareNetworkPassword.toCharArray(), ApplicationCore.hardwareNetworkDomain);
    com.hierynomus.smbj.session.Session session = connection.authenticate(ac);

    // Connect to Share
    try (DiskShare share = (DiskShare) session.connectShare(ApplicationCore.hardwareNetworkVolume)) {
        Set<AccessMask> accessMasks = new HashSet<>();
        accessMasks.add(AccessMask.FILE_LIST_DIRECTORY);
        // Open the root share folder
        try (Directory directory = share.openDirectory(ApplicationCore.hardwareNetworkFolder, accessMasks, null,
                SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null)) {
            // Track all changes until program is terminated
            while (true) {
                Set<SMB2CompletionFilter> completionFilter = new HashSet<>();
                completionFilter.add(SMB2CompletionFilter.FILE_NOTIFY_CHANGE_FILE_NAME);
                SMB2ChangeNotifyRequest request = new SMB2ChangeNotifyRequest(
                        session.getConnection().getNegotiatedProtocol().getDialect(),
                        session.getSessionId(),
                        share.getTreeConnect().getTreeId(),
                        directory.getFileId(),
                        completionFilter,
                        65536,
                        true);

                Future<SMB2ChangeNotifyResponse> future = session.send(request);



                SMB2ChangeNotifyResponse response = future.get();
                // just some output to make life easier
                for (SMB2ChangeNotifyResponse.FileNotifyInfo notifyInfo : response.getFileNotifyInfoList()) {
                    System.out.println(notifyInfo);
                }
                System.out.println();

           // }
        }
    }
}

这是我的新代码,具有可观察性。 onChange代码将立即调用,而不是在文件更改时调用。

public static void smbjWatch() throws Exception {

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMo

de.setThreadPolicy(policy);


        SmbConfig config = SmbConfig.builder()
                .withMultiProtocolNegotiate(true)
                .withDfsEnabled(true)
                .withNegotiatedBufferSize()
                .withTimeout(120, TimeUnit.SECONDS) // Timeout sets Read, Write, and Transact timeouts (default is 60 seconds)
                .withSoTimeout(180, TimeUnit.SECONDS) // Socket Timeout (default is 0 seconds, blocks forever)
                .build();

        SMBClient smbClient = new SMBClient(config);
        Connection connection = null;
        try {
            connection =  smbClient.connect(ApplicationCore.hardwareNetworkIp);
        } catch (IOException e) {
            e.printStackTrace();
        }

        AuthenticationContext ac = new AuthenticationContext(ApplicationCore.hardwareNetworkLogin, ApplicationCore.hardwareNetworkPassword.toCharArray(), ApplicationCore.hardwareNetworkDomain);
        com.hierynomus.smbj.session.Session session = connection.authenticate(ac);

        // Connect to Share
        try (DiskShare share = (DiskShare) session.connectShare(ApplicationCore.hardwareNetworkVolume)) {
            Set<AccessMask> accessMasks = new HashSet<>();
            accessMasks.add(AccessMask.FILE_LIST_DIRECTORY);
            // Open the root share folder
            try (Directory directory = share.openDirectory(ApplicationCore.hardwareNetworkFolder, accessMasks, null,
                    SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null)) {
                // Track all changes until program is terminated

                    Set<SMB2CompletionFilter> completionFilter = new HashSet<>();
                    completionFilter.add(SMB2CompletionFilter.FILE_NOTIFY_CHANGE_FILE_NAME);
                    SMB2ChangeNotifyRequest request = new SMB2ChangeNotifyRequest(
                            session.getConnection().getNegotiatedProtocol().getDialect(),
                            session.getSessionId(),
                            share.getTreeConnect().getTreeId(),
                            directory.getFileId(),
                            completionFilter,
                            65536,
                            true);

                    Future<SMB2ChangeNotifyResponse> future = session.send(request);

                    Observable.fromFuture(session.send(request), Schedulers.io())
                            .doOnSubscribe(disposable ->session.send(request).get())
                            .subscribeOn(Schedulers.io())
                            .doOnNext(response -> { onChange((SMB2ChangeNotifyResponse)response); } )
                            .subscribe( response -> { onChange((SMB2ChangeNotifyResponse)response); }
                            );
            }
        }
    }


    private static void onChange(SMB2ChangeNotifyResponse response) {
        for (SMB2ChangeNotifyResponse.FileNotifyInfo notifyInfo : response.getFileNotifyInfoList()) {
            System.out.println(notifyInfo);
            Log.d("TAG",notifyInfo.getFileName());
        }
    }

我不太会观察......

0 个答案:

没有答案