Textdatei auslesen und über Mqtt schicken

Bitte aktiviere JavaScript!
K

kevmitnick

Ich will eine Textdatei auslesen, in der zeilenweise jeweils irgendwas steht. Anschließend soll das ausgelesene an einen Mqtt Broker (Mosquitto) versendet werden, sodass ein anderer Client es empfangen kann. Der Transport via Mqtt ist mir soweit klar, ich hänge nur noch daran die entsprechenden Zeichen zu übergeben. Hier mal ein Auszug aus meinen bisherigen Klassen zum Auslesen der Datei und der anschließenden Übertragung per Mqtt.

Java:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FileScanner {
      
       public static void main (final String[] args) throws FileNotFoundException{
                          
             final List<String> uoData = new ArrayList<>();
             final String pathname = "C:/Users/.../test.txt";
             final File txtFile = new File(pathname);
            
             final Scanner scanner = new Scanner(txtFile);
             while(scanner.hasNextLine()) {
                    final String line = scanner.nextLine();
                    uoData.add(line);
             }
             scanner.close();
            
             /*for(int i = 0; i < uoData.size(); i++) {
                    System.out.println(uoData.get(i));
             }*/
       }
}
Dieser Teil liest meine Textdatei aus, was soweit auch gut funktioniert. Der auskommentierte Teil diente lediglich der Überprüfung.


Java:
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class Publish {
       public static void main(final String[] args) throws MqttException{
            
             final String broker = "tcp://...";
             final String topicName = "demo/1";
             final int qos = 2;
            
             final MqttClient client = new MqttClient(broker, MqttClient.generateClientId());
            
             final MqttConnectOptions connOpts = new MqttConnectOptions();
             connOpts.setCleanSession(false);
             connOpts.setKeepAliveInterval(1000);
            
             final MqttMessage message = new MqttMessage(s.getBytes());
             message.setQos(qos);
             message.setRetained(true);
                                              
             client.connect(connOpts);
             client.getTopic(topicName).publish(message);
            
       }
}
Hier steht soweit auch alles, bis auf den String der übergeben werden soll. Wenn ich beispielsweise String s = "HelloWorld" setze, wird HelloWorld an den MqttBroker übergeben. Aber wie kann ich die ArrayList uoData aus dem FileScanner an den Broker übergeben?
Prinzipiell brauch ich ja nur Zugriff auf uoData, dann kann ich ja mittels for Schleife, die ArrayList auslesen.
Java:
for(int i = 0; i < uoData.size(); i++){
    String s = uoData.get(i);
}
Aber wie komme ich an uoData ran, wenn ich mich in der Klasse Publish befinde?
 
Aber wie komme ich an uoData ran, wenn ich mich in der Klasse Publish befinde?
Es gibt da mehrere Möglichkeiten, aber generell sollte man getrennte Funktionalitäten in separaten Klassen kapseln. Ich würde demnach die Methode main() aus deinen beiden bisherigen Klassen entfernen und in eine dritte Klasse verlagern. In dieser Klasse kannst du eine Instanz von FileScanner und eine Instanz von Publish(er) erzeugen und verwenden. Du musst diese beiden Klassen nur um

- eine gettermethode zum Auslesen der Liste
- eine publish(List<String> data)-Methode zur Übergabe der Liste

ergänzen.

Den Pfad zur Datei würde ich im Konstruktor des FileScanners übergeben und die Verbindungsdaten im Konstruktor des Publishers.

Damit kommt ungefähr folgendes heraus:
Java:
public static void main(final String[] args) {
    fileScanner = new FileScanner("C:/Users/.../test.txt");
    publisher = new Publisher("tcp://...", "demo/1");

    publisher.publish(fileScanner.getData());
}
Evtl. gehört der TopicName auch als zusätzlicher Parameter zu publish(), anstatt in den Konstruktor. Ich kenne Mqtt nicht.
 
Zuletzt bearbeitet:
K

kevmitnick

Danke, habe es aber noch nicht so ganz verstanden.
Für meine FileScanner Klasse, zwei Methoden:

Code:
private read() throws FileNotFoundException{
                
        final List<String> uoData = new ArrayList<>();
        final String pathname = "C:/.../test.txt";
        final File txtFile = new File(pathname);
        
        final Scanner scanner = new Scanner(txtFile);
        while(scanner.hasNextLine()) {
            final String line = scanner.nextLine();
            uoData.add(line);
        }
        scanner.close();
        
        /*for(int i = 0; i < uoData.size(); i++) {
            System.out.println(uoData.get(i));
        }*/
    }
    
    private getData() {
        
    }
Aber wie sehen hierbei die Methodenköpfe aus? Also brauche ich Rückgabewerte oder habe ich void Methoden?
Die gleiche Frage auch für meine Methode send() in der Klasse Publish.

Java:
private send() throws MqttException{
        
        final String broker = "tcp://...";
        final String topicName = "demo/1";
        final int qos = 2;
        
        final MqttClient client = new MqttClient(broker, MqttClient.generateClientId());
        
        final MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setCleanSession(false);
        connOpts.setKeepAliveInterval(1000);
        
        final MqttMessage message = new MqttMessage(s.getBytes());
        message.setQos(qos);
        message.setRetained(true);
                            
        client.connect(connOpts);
        client.getTopic(topicName).publish(message);
        
    }
Was muss ich hier entfernen/ergänzen?
 
K

kevmitnick

So ich muss es jetzt zur Verständnis hier nochmal niederschreiben, damit ich es kapiere.
Ich habe eine Klasse FileScanner, die das Attribut uoData besitzt, bei dem es sich um eine leere ArrayList handelt.
Außerdem besitzt diese Klasse die Methode readFile(), die die Datei ausliest. Diese Mehtode muss das File txtFile übergeben bekommen, damit sie weiß was ausgelesen werden soll. Außerdem brauch man noch eine getUoData() Methode, die die befüllte ArrayList uoData zurück gibt.

Code:
public class FileScanner {
    
    List<String> uoData = new ArrayList<>();
    
    ... readFile() throws FileNotFoundException {
    
        Scanner scanner = new Scanner(txtFile);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            uoData.add(line);
        }
        scanner.close();
    }
    
    ... List<String> getUoData(...) {
    
        return uoData;
    }
}
Bei den Punkten bin ich mir nicht sicher, ob public/private/protected bzw. der jeweilige Parameter.
Das ist der eine Teil. Also ist das bisher korrekt und was muss für die Punkte rein?

In der Klasse Publisher brauchen wir die Attribute broker, topicName und die beschrieben ArrayList uoData. Außerdem muss die Klasse über die Methode send() verfügen, die die Inhalte der ArrayList byteweise ausliest und dann an den Broker und einem bestimmten topicName verschickt.

Java:
public class Publisher{

    ???
    
    ??? send(???) throws MqttException {
    
        MqttClient client = new MqttClient(broker, MqttClient.generateClientId());
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setCleanSession(false);
        connOpts.setKeepAliveInterval(1000);
        
        MqttMessage message = new MqttMessage(???.getBytes());
        message.setQos(2);
        message.setRetained(true);
        
        client.connect(connOpts);
        client.getTopic(topicName).publish(message);
    }
    
    ???
              
    
}
Hier bin ich mir bei allen Fragezeichen nicht sicher.

Bitte kann mir jemand behilflich sein, sodass ich es verstehe.
 
Mein Rat wäre, dich erst mit den Grundlagen von Java zu beschäftigen, bevor du dich mit sowas wie MQTT beschäftigst.
Man könnte dir natürlich alles vorsagen, aber ist das sinnvoll?
 
Passende Stellenanzeigen aus deiner Region:

Oben