PROBLEMA Capire EOF - [end of file] in Java

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
Produttore
Java:
package fileproducer;

import java.util.*;
import java.io.*;
import java.nio.file.*;
import java.io.File;
import java.lang.String;
/**
 *
 * @author zabit
 */
public class FileProducer extends Thread implements Runnable
{
    private boolean finish;
        
    private String p;
    
    private int s;
    
    public FileProducer(){
        System.out.println("FileProducer constructor.");
        this.finish = false;
        this.p = new String("/home/zabit/NetBeansProjects/FileProducer/out/out.txt");
        this.s = 60000;
    }
    
    public void run() {
        System.out.println("run method");

        try {
            Thread.sleep(s);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();  //set the flag back to <code>true
        }
        System.out.println("Non sono piu in attesa");
        this.finish = true;
    }
    
    public boolean getFinish(){
        return this.finish;
    }
    
    public void begin(){
        System.out.println("begin method");
        
        try{
            System.out.println(p);
            FileOutputStream fos = new FileOutputStream(p, true);
      
        
            while(this.getFinish() == false)
            {
                byte[] tb = "ciao mamma\n".getBytes();
                fos.write(tb);
            }
            
            System.out.println("Ho smesso di scrivere.");
            fos.close();
            
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    /**
     * @param args the command line arguments
     */   
    public static void main(String args[])  {
        
        FileProducer fp = new FileProducer();
        fp.start();
        fp.begin();
    }
    
}
Consumatore
Java:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fileconsumer;

import java.nio.file.*;
import java.lang.String;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Timer;
import java.util.TimerTask;

/**
 *
 * @author zabit
 */
public class FileConsumer {
    private int c;
/**
    * @param args
    */
    
    public FileConsumer(){
        File file = new File("/home/zabit/NetBeansProjects/FileProducer/out/out.txt");
        this.c = 0;
        try {
            RandomAccessFile r = new RandomAccessFile(file, "r");
            //First time read
            String str = null;
            while((str = r.readLine()) != null) {
                System.out.println("str:"+str);
            }
            r.seek(r.getFilePointer());
            startTimer(r);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        FileConsumer fc = new FileConsumer();
    }
 
    private void startTimer(final RandomAccessFile r) {
        System.out.println("method startTimer");
        Timer timer = new Timer();
        
        timer.scheduleAtFixedRate(new TimerTask() {
            private int c;
            
            protected void TimerTask(){
                this.c = 0;
            }
            
            @Override
            public void run() {
                this.c++;
                String str = null;
                try {
                    while((str = r.readLine()) != null) {
                        System.out.println("c:"+c+"|"+str);
                    }
                    r.seek(r.getFilePointer());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }, 0, 1000);
    }
}

Il produttore scrive in un file out.txt la frase "ciao mamma" andando a capo tutte volte per una durata di 1 minuto.
Il consumatore deve essere eseguito MENTRE il produttore produce il file out.txt.


Ecco cosa succede, Il consumatore NON SA mai la la fine del file Quindi legge costantemente la frase "ciao mamma".
Come si fa a sapere quando il produttore ha terminato di scrivere su file e quindi il consumatore deve "rileggere" il file per intero e riprendere la lettura da dove era rimasto?
Potete aiutarmi in questo dubbio, ci sbatto la testa ma.
 

Andretti60

Utente Èlite
6,440
5,091
non e' ben chiaro quello che stai cercando di fare.
La classe FileProducer scrive una frase nel file in un loop molto stretto, senza interruzione alcuna per un certo numero di minuti, per cui la classe FileConsumer non e' capace di leggerlo tutto, rimarrà sempre indietro e quindi non raggiungerà mai il EOF finche' FileProducer chiude il file. Prova ad aggiungere uno sleep() dentro il while() del metodo begin().
 

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
non e' ben chiaro quello che stai cercando di fare.
La classe FileProducer scrive una frase nel file in un loop molto stretto, senza interruzione alcuna per un certo numero di minuti, per cui la classe FileConsumer non e' capace di leggerlo tutto, rimarrà sempre indietro e quindi non raggiungerà mai il EOF finche' FileProducer chiude il file. Prova ad aggiungere uno sleep() dentro il while() del metodo begin().
Intenzionalmente è fatto così In pratica nel problema reale inizio una chiamata telefonica e questa verrà registrata su file. La chiamata verrà registrata perché devo trasferire audio del cliente per essere ascoltato da dieci taxisti. Il flusso di registrazione della chiamata è continuo e SCUSA non puoi chiuderlo così hai la fine del file? No perché uno tra i dieci taxisti dovrà dire "sono il taxi 1234 passo io a prenderla". Quando il cliente riceve risposta ( ancora devo capire come implementare questo ultima parte ) chiudo la chiamata e anche la registrazione e anche la comunicazione con i dieci taxi. Quindi per vedere se era fattibile lo scenario ho improvvisato un produttore e consumatore che una volta che il produttore è lanciato scrive il messaggio su file continuamente ( così il file cresce ) mentre il consumatore LANCIATO SUBITO DOPO il produttore che intanto scrive, legge il messaggio da file.

Per ultimo punto credo non sia fattibile, vorrei prendere dei dati audio dal socket (la risposta di uno dei dieci taxisti) ed mandarli sulla linea telefonica ed eseguirli (audio) così il cliente ha la risposta.

nel problema reale ho questo scenario
1 il cliente chiama telefonicamente il servizio taxi like, risponde operatore.
2 l' operatore dice al cliente come posso aiutarla e quello che dice verrà sentito da dieci taxisti.
3 i dieci taxisti sono collegati in una stanza in cui possono comunicare tra loro tramite socket.
4 il taxista risponde all audio del cliente ma come inserisco questa risposta nel canale della telefonata?
5 il cliente riceve la risposta lungo il canale telefonico e chiude la chiamata con l operatore.
Post unito automaticamente:

Un possibile work around

il flusso continuo lo spezzo in più file, mi rimane ultimo pezzo di file che è continuo ma prima o poi quel ultimo pezzo di file termina Così ho tanti piccoli files chiusi e solo uno potenzialmente che cresce aperto ma che velocemente trascorsi n minuti terminerà.
 
Ultima modifica:

fededevi

Utente Attivo
37
4
Fare una copia della chiamata su file e fare lo streaming dei dati ai 10 nodi sono due problemi diversi e ben distinti.

Non mi è chiaro poi se i 2 processi di "produttore" e "consumatore" debbano essere separati come nel codice di esempio.
Se la risposta è no allora non ti serve leggere i dati dal file per mandarli ai nodi, puoi mandarli direttamente dallo stesso processo ad esempio utilizzando strutture apposite come code concorrenti dove un thread scrive e un 'altro legge in sicurezza.
Se la risposta è si, utilizzare file per fare I.P.C. è una pessima idea. Usa socket o una delle tante librerie apposite (e.g. zmq).
 

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
1 - Un utente chiama telefonicamente il server asterisk e registra la chiamata telefonica su file wav.

Fare una copia della chiamata su file e fare lo streaming dei dati ai 10 nodi sono due problemi diversi e ben distinti

In tempo reale mentre si registra la chiamata deve essere possibile inviare il file audio wav ai 10 nodi in modo che tutti lo possano ascoltare.
ECCO perchè mi serve un PRODUTTORE e CONSUMATORE, perchè mentre viene registrata la chiamata che potrebbe essere ancora in corso (produce continuamente byte) devo nel frattempo anche inviare questo flusso tramite socket ai nodi.

Ho quindi saltato la parte di registrazione e creato un Mock di prova che simula un produttore che scrive per 10 minuti su un file e il consumatore consuma da questo file leggendo e inviando il contenuto su socket.

2 - Ogni nodo è dotato di microfono.
Il server dovrebbe fare da dispatcher cioè lo stream di un client va inviato ad altri 9 client perchè tutti devono ascoltare tutti.Il problema si riduce a creare socket stream e file audio per ascolto.

NB: Perchè mi serve creare i file, non posso tenermi solo il flusso? Il file audio wav è strutturato con un HEADER e DATA. No, non posso tenermi solo l'header perchè se voglio che lo stream sia "ascoltabile" devo specificare nell'header LA LUNGHEZZA del file audio (100k di esempio). Essendo lo stream un componente dinamico non ho mai la lunghezza quindi mi serve spezzare lo stream in piu parti, e creare per ogni parte il file audio.
 

fededevi

Utente Attivo
37
4
Ho quindi saltato la parte di registrazione e creato un Mock di prova che simula un produttore che scrive per 10 minuti su un file e il consumatore consuma da questo file leggendo e inviando il contenuto su socket.
Il file audio wav è strutturato con un HEADER e DATA.[...]

Ancora non vedo buone ragioni per salvare il flusso audio su file. Perchè non gestisci tutto in memoria (assumendo che sia un processo con 2 thread) o, se hai 2 processi, non usi una libreria per l'ipc?

Sei sicuro che utilizzare waw per fare streaming sia una buona idea? Hai calcolato la banda che ti serve?
 

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
Ancora non vedo buone ragioni per salvare il flusso audio su file. Perchè non gestisci tutto in memoria (assumendo che sia un processo con 2 thread) o, se hai 2 processi, non usi una libreria per l'ipc?

Sei sicuro che utilizzare waw per fare streaming sia una buona idea? Hai calcolato la banda che ti serve?
Potrei usare anche MP3, devo verificare nell' impostazioni di asterisk i formati che gestisce.

Ma quindi mi consigli di usare la comunicazioni tra processi?

Gestisco tutto in memoria ma come faccio a mettere una telefonata VoIP in memoria se non la salvo prima su file?

intendi che potrei gestire lo AudioInputStream in memoria inviando su socket lo stream al client e il client non deve nemmeno salvare su file ma leggere lo stream a chunk(a causa del fatto che devono avere una length questi file audio) così da creare l'audio per ascoltarlo.

Ci provo
 

fededevi

Utente Attivo
37
4
Ma tu vuoi leggere da file perché asterisk ti genera un file mentre è in ascolto ed è l'unico modo che hai per accedere a quei dati?
Non conosco assolutamente asterisk ma ho visto che è open source, forse c'è un modo per intercettare le chiamate direttamente facendo qualche modifica?
 
Ultima modifica:

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
Ma tu vuoi leggere da file perché asterisk ti genera un file mentre è in ascolto ed è l'unico modo che hai per accedere a quei dati?
Non conosco assolutamente asterisk ma ho visto che è open source, forse c'è un modo per intercettare le chiamate direttamente facendo qualche modifica?
Infatti è per non complicarmi la vita. Si l'utente chiama Asterisk che risponde, Asterisk fa anche da SIP client. Ora non ho un modo per mettermi in ascolto della chiamata generata ma posso registrare la chiamata su file e ascoltare il file. Sarebbe senza dubbio meglio mettermi in ascolto della chiamata direttamente ma non so come si possa fare.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!