Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

Lecture fichier via url ou file, différence ?


Sujet :

Entrée/Sortie Java

  1. #1
    Membre habitué
    Lecture fichier via url ou file, différence ?
    Bonjour et bonne année à tous !

    Je vous pose la question suivante, à savoir y a-t-il une différence (ou plusieurs) entre une lecture de fichier en local et via url.

    Pour etre plus clair, voici une partie du code sur lequel je bute :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    //--- reads the font file
    File myFontFile = new File(theFileLocat);
    InputStream myFis = null;
    if (!myFontFile.exists()) {
    	try {
    		//myFis = (FileInputStream) (new URL(theFileLocat).openStream());
    		myFis = (new URL(theFileLocat).openStream());
    	} catch (MalformedURLException e) {		
    		throw new IOException("Kanji Font file '"+theFileLocat+"' is not accessible");
    	}
    } else {
    	myFis = new FileInputStream(myFontFile);			
    }
     
    while ( myFis.read(myTabRead) > 0) {
     
    	//--- builds the key
    	myKey = new byte[2];
     
    	//--- initialisation of key
    	myKey[0] = myTabRead[0];
    	myKey[1] = myTabRead[1];
     
    	//--- new font
    	myFont = new byte[106];
    	System.arraycopy(myTabRead, 0, myFont, 0, myFont.length);
     
    	//--- fills the Kanji table
    	getKanjiTable().put(new Integer(byteToShort(myKey)), myFont);
    }


    La première partie du code (avant la lecture du fichier, le while donc) consiste à créer le flux de lecture. Si le fichier passé en paramètre n'existe pas localement, on tente d'effectuer une lecture via url dessus.
    La deuxieme partie du code lit le fichier et le load en mémoire dans une hashtable.

    Mon problème est que la lecture du fichier en question est complète lorsque je passe par le fichier local, et incomplète losque la lecture se fait via URL (le fichier est situé sur un serveur distant).

    Voilà donc mon probleme, tout est nickel en local, mais à distance ca foire. La lecture s'arrete aléatoirement à peu pres à la moitié du fichier pour vous donner un ordre d'idée.

    Quelles sont les différences entre lecture de fichier en local et lecture de fichier via url ?

    Un grand merci à vous si vous pouvez m'aider (et oui je n'ai que ca ^^).

  2. #2
    Rédacteur

    Bah ca devrait marcher...

    La difference c'est que File accede directement au Systeme de fichier de l'OS et que URL utilise la pile de protocole réseau, en l'occurence HTTP sur TCP/IP.

    un probleme de timeout peut-etre ? Essaye de jouer avec URLConnection.setReadTimeout()...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Membre chevronné
    Citation Envoyé par pseudocode
    Bah ca devrait marcher...

    La difference c'est que File accede directement au Systeme de fichier de l'OS et que URL utilise la pile de protocole réseau, en l'occurence HTTP sur TCP/IP.

    un probleme de timeout peut-etre ? Essaye de jouer avec URLConnection.setReadTimeout()...
    Ca marche aussi si la machine n'a pas d'interface eth0 ? ( je n'ai pas testé ).

  4. #4
    Rédacteur

    oui ca marche aussi. Dans ce cas ca passe par le loopback (lo0)
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  5. #5
    Membre habitué
    Pour commencer merci pour vos réponses à tout deux

    Tout fonctionne en temps normal effectivement.
    J'ai avancé un peu dans mon problème et il se trouve que ca n'a finalement rien a voir avec le type de connection utilisé.
    La premiere partie du code peut etre oubliée donc.

    Dans la partie suivante :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    int myRet = -1;
    int compteur = 0;
    while ( ( myRet = myFis.read(myTabRead)) > 0) {
     
    	//--- builds the key
    	compteur += myRet;
    	myKey = new byte[2];
    	//--- initialisation of key
     
    	System.out.println();
     
    	myKey[0] = myTabRead[0];
    	myKey[1] = myTabRead[1];
     
    	//--- fills the Kanji table
    	getKanjiTable().put(new Integer(byteToShort(myKey)), myTabRead);
     
    }
     
    System.out.println("Taille totale loadée : "+compteur);
    System.out.println("Nombre d'entrée dans la table : "+getKanjiTable().size());


    J'ai laissé un System.out.println au milieu et qui a-priori ne sert à rien. Tel quel tout fonctionne bien. Si j'ote le System.out.println rien ne fonctionne.
    J'ai déjà eu ce probleme il y a un bon moment en C et il me semblait que ca venait d'un problème de mémoire ou de flush... mais je ne sais plus trop.

    Auriez-vous déjà eu le meme problème, à savoir que votre programme plante si vous ne mettez pas un System.out au bon endroit ?


    Edit : en fait lorsque j'affiche la taille du fichier traité et le nombre d'entrée dans ma hashtable, je me rends compte que le fichier a bien été lu en entier, mais que dans la hashtable tout n'as pas été mis... je me pense donc en ce moment sur un problème lié à la méthode put des hashtables (peut etre) et au vidage de tampon mémoire de lecture, du tableau...

  6. #6
    Membre chevronné
    Le flush c'est sur les outputStream.
    Sinon une erreur classique : fermes-tu bien TOUS tes flux via leur méthode close() ?

  7. #7
    Rédacteur

    A mon avis, le System.out.println() ralentit ta boucle, ce qui laisse le temps aux données d'arriver. C'est donc bien un probleme de disponnibilité des données dans l' InputStream.

    Il va falloir changer la boucle "while" pour:

    1. Sortir quand TOUTES les données sont lues
    2. Attendre quand l'InputStream est vide mais que TOUTES les données ne sont pas encore lues

    Le mieux serait de connaitre la longueur des données AVANT de rentrer dans le "while". Il faut regarder du coté de la methode getContentLength() pour URL et length() pour FILE.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  8. #8
    Membre habitué
    oui je ferme juste apres l'affichage de la facon suivante :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    myFis.close();


    Sinon, je remet ma remarque que j'ai éditer dans le message précédent.
    Je me rends compte suite à l'affichage de la taille totale lu sur le fichier et du nombre d'entrée dans ma hashtable, que le fichier est bien lu en entier, mais qu'il n'y a pas le bon nombre d'entrée dans ma hashtable. (seulement la moitier) lorsque je ne met pas le sysout.


    EDIT : lol, ca va vite aujourdh'ui c'est cool

    Pour ce qui est de ta remarque Pseudocode j'y ai déjà pensé et j'ai testé avec un Thread.sleep() sur 10 secondes pour voir ce qui se passait, car je me suis effectivement apercu qu'en mode debug avec un breakpoint ca ne plante pas.

    Mais la méthode d'attente ne fonctionne pas plus... je vais voir ce que tu viens de me dire.

  9. #9
    Rédacteur

    Citation Envoyé par kij

    Sinon, je remet ma remarque que j'ai éditer dans le message précédent.
    Je me rends compte suite à l'affichage de la taille totale lu sur le fichier et du nombre d'entrée dans ma hashtable, que le fichier est bien lu en entier, mais qu'il n'y a pas le bon nombre d'entrée dans ma hashtable. (seulement la moitier) lorsque je ne met pas le sysout.
    ???

    Bah la c'est un probleme dans ton algo. Elle est initalisée comment la variable myTabRead ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  10. #10
    Membre habitué
    comme suit :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    byte[] myTabRead = new byte[106];


    juste avant la boucle de lecture.

    Mais je pense que ce que tu as soulevé est mon problème, car le programme se déroule très bien lorsque je suis en mode debug et que j'attends un moment après la boucle. (point d'arret juste apres la boucle).

  11. #11
    Rédacteur

    Mmhhh...

    Donc a chaque boucle du while on lit entre 0 et 106 octets
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    myFis.read(myTabRead)


    Mais dans le corps du while on n'en traite que 2:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    myKey[0] = myTabRead[0];
    myKey[1] = myTabRead[1];


    Donc, potentiellement, on en perd 104 !!


    Essaye de declarer myTabRead comme ca:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    byte[] myTabRead = new byte[2];
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  12. #12
    Membre habitué
    non on ne perd pas de donnée en fait.

    Les deux premiers byte servent à faire une clé :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myKey = new byte[2];
    myKey[0] = myTabRead[0];
    myKey[1] = myTabRead[1];


    puis on met le couple clé/myTabRead dans la hashtable :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    getKanjiTable().put(new Integer(byteToShort(myKey)), myTabRead);


    De maniere à en faire un couple unique et pouvoir retrouver les valeurs par la suite.

  13. #13
    Rédacteur

    Arf. ok.... Sauf que tu sauve toujours la meme reference "myTabRead" dans la map
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    getKanjiTable().put(new Integer(byteToShort(myKey)), myTabRead);


    Il faudrait copier les données dans un nouveau tableau avant chaque "put", comme tu le faisais dans ton premier source.

    M'enfin quand meme, affiche la valeur de "myRet" dans la boucle, histoire de voir si tu lis tjrs la bonne taille de donnée.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  14. #14
    Membre habitué
    oui j'ai remis avec le tableau intermédiaire entre temp, mais ca ne change rien.
    Sans tableau ca marche tout aussi bien puisque la méthode put copie les données (mais pas les clés) il me semble, il n'y a donc qu'à reinitialiser les clés normalement.
    Enfin là n'est pas le soucis de toute maniere.

    J'ai bien 106 de lu à chaque passage de boucle et j'ai ajouté un :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    System.out.println(myFis.available());


    pour voir le comportement de la lecture. Tout se passe bien, c'est lu aussi par coup de 106 et alimenté à mesure que c'est lu.



    Je pense que le pb ne viens pas de l'algo car il fonctionne très bien sur des File.
    Bon en temps normal je serais tenter de faire une redirection de la sortie sur null juste avant la boucle et de laisser le sysout, mais bon... c'est pas tres pro ^^

  15. #15
    Rédacteur

    Citation Envoyé par kij

    Sans tableau ca marche tout aussi bien puisque la méthode put copie les données (mais pas les clés) il me semble, il n'y a donc qu'à reinitialiser les clés normalement.
    Ah bon ? Perso, j'en doute, mais ce n'est pas le pb pour l'instant.

    Question: Comment sais-tu qu'il n y a pas le bon nombre d'entrée dans ta hashtable ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  16. #16
    Membre habitué
    lorsque je fais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    System.out.println("Nombre d'entrée dans la table : "+getKanjiTable().size());


    Il devrait me sortir le chiffre 8272. Or généralement ca s'arrete aux alentours de 5000 quand ca ne fonctionne pas.

  17. #17
    Membre habitué
    Je ré-édit le code ici :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    byte[] myTabRead = new byte[106];
    byte[] myFont = null;
    byte[] myKey = null;
     
    int myRet = -1;
    int compteur = 0;
     
    while ( ( myRet = myFis.read(myTabRead)) > 0) {
     
    	//--- builds the key
    	compteur += myRet;
    	myKey = new byte[2];
     
    	//--- initialisation of key	
    	myKey[0] = myTabRead[0];
    	myKey[1] = myTabRead[1];
     
    	System.out.println("num car read : "+myRet);
     
    	//--- new font
    	myFont = new byte[106];	
    	System.arraycopy(myTabRead, 0, myFont, 0, myTabRead.length);
     
    	//--- fills the Kanji table
    	getKanjiTable().put(new Integer(byteToShort(myKey)), myFont);
     
    }
     
    System.out.println("Taille totale loadée : "+compteur);
    System.out.println("Nombre d'entrée dans la table : "+getKanjiTable().size());
     
    myFis.close();

  18. #18
    Rédacteur

    J'ai essayé ton code chez moi et ca marche bien.

    Enfin bon, j'ai du réécrire la methode byteToShort() et mettre un try/catch IOException pour que ca compile.

    J'ai pas de texte en kanji sous la main, mais ca marche avec du katagana
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  19. #19
    Membre habitué
    et ca marche comment ? Via url ou via file en local ?

    Oui de toute manière le type de fichier on s'en fiche

    Bon.. ca pourrait venir de chez moi alors.

  20. #20
    Rédacteur

    Les 2 mon general.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
     
    public class testStream {
     
    	private Map kanjiTable = new HashMap();
     
    	public void test(InputStream myFis) throws IOException {
     
    		byte[] myTabRead = new byte[106];
    		byte[] myFont = null;
    		byte[] myKey = null;
     
    		int myRet = -1;
    		int compteur = 0;
     
    		while ( ( myRet = myFis.read(myTabRead)) > 0) {
     
    			//--- builds the key
    			compteur += myRet;
    			myKey = new byte[2];
     
    			//--- initialisation of key	
    			myKey[0] = myTabRead[0];
    			myKey[1] = myTabRead[1];
     
    			System.out.println("num car read : "+myRet);
     
    			//--- new font
    			myFont = new byte[106];	
    			System.arraycopy(myTabRead, 0, myFont, 0, myTabRead.length);
     
    			//--- fills the Kanji table
    			kanjiTable.put(new Integer(byteToShort(myKey)), myFont);
    		}
     
    		System.out.println("Taille totale loadée : "+compteur);
    		System.out.println("Nombre d'entrée dans la table : "+kanjiTable.size());
     
    		myFis.close();
    	}
     
     
    	private int byteToShort(byte[] myKey) {
    		int i = (myKey[0]*256)+myKey[1];
    		return i;
    	}
     
    	public static void main(String[] args) {
    		InputStream myFis = null;
     
    		String theFileLocat = "tmp/testfile.txt";
     
    		try {
    			// http
    			//myFis = (new URL("http://localhost:80/"+theFileLocat).openStream());
     
    			// file
    			//myFis = new FileInputStream("C:/webroot/"+theFileLocat);
    		} catch (Exception e) {		
    			e.printStackTrace();
    			return;
    		}
     
    		try {
    			new testStream().test(myFis);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
     
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.