我需要监视文件夹中的文件更改。 我使用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());
}
}
我不太会观察......