2016-03-14 1 views
0

j'ai vu comme ça, toujours:Une seule ligne en utilisant écriture et de lecture de flux Java

int count = line.read(buffer, 0, buffer.length); 
if (count > 0) { 
    out.write(buffer, 0, count); 
} 

Autre exemple

byte[] buffer = new byte[1024]; // Adjust if you want 
int bytesRead; 
while ((bytesRead = input.read(buffer)) != -1) { 
    output.write(buffer, 0, bytesRead); 
} 

autres ...

int numRead; 
    while ((numRead = is.read(buf)) >= 0) { 
     os.write(buf, 0, numRead); 
    } 

Je ne ai jamais vu quelque chose comme ceci:

while (true) { 
    try { 
     output.write(BytesArray, 0, input.read(BytesArray, 0, BytesArray.length)); //Single line for read and write!!!! 
    } catch (IOException e) { 
     System.out.println("I can't write!"); 
     break; 
    } catch (ArrayIndexOutOfBoundsException e) { 
     System.out.println("I can't read!"); 
     break; 
    } 
    } 

Quel est le problème d'utiliser un OuputStream Writing lu par InputStream récemment lu?

Y at-il un problème?

EDIT InputStream.read fonctionne précisément quand OutputStream.write œuvres, et échoue lorsque l'autre échoue aussi; de la même manière OutputStream.write fonctionne quand InputStream.read fait ainsi et s'arrête lorsque l'autre ne parvient pas à le faire. Lorsque InputStream.read(...) échoue (ou ne peut pas lire plus), cette méthode renvoie -1; mais, quand OutputStream.write(...) échoue (ou ne peut pas écrire plus) cette méthode jette une exception IOException.

Personnellement, je crois que: lorsque OutputStream.write(...) ne peut pas écrire devrait retourner "-1" exactement de la même manière que le fait InputStream.read(...) quand ne peut pas lire.

QUESTION: -vous que InputStream.read(...) et OutputStream.write(...) ils devraient être traités de la même manière (rendements -1)?

NOTE: Je sais que cette méthode pour OutputStream: public void write(...)

+1

L'utilisation de la gestion des exceptions pour exécuter le flux de contrôle - en particulier lorsque cela n'est pas nécessaire en raison de l'API - est une mauvaise pratique. –

+1

"Ligne unique pour lire et écrire !!!!" Dommage pour toutes les autres lignes supplémentaires. –

+0

@AndyTurner merci Andy, quand le 'InputStream.read (...)' renvoie '-1' l'ArrayIndexOutOfBoundsException sera levé, alors il est nécessaire de séparer les lignes pour lire et écrire. Mais quelle est l'alternative à 'catch (ArrayIndexOutOfBoundsException e)' en utilisant une seule ligne? –

Répondre

2

En utilisant la gestion des exceptions pour effectuer le flux de contrôle - quand il est inutile en raison de l'API - est une mauvaise pratique. Si votre raison de vouloir le faire est de pouvoir écrire des instructions sur une ligne, vous devez évaluer les raisons pour lesquelles vous pensez qu'il est préférable d'écrire les instructions sur une ligne. Mon téléphone a un écran suffisamment grand pour afficher tous les quatre exemples ci-dessus en même temps - et je ne code pas sur mon téléphone - donc je ne peux pas imaginer une situation où écrire quelque chose sur une seule ligne "parce que je peux écrire sur une seule ligne "est une raison convaincante.

En outre, examiner si le fait que vous êtes capable d'écrire certains des déclarations sur une seule ligne qui fait vraiment le code plus court global:

while (true) { 
    try { 
    output.write(buffer, 0, input.read(buffer, 0, buffer.length); 
    } catch (ArrayIndexOutOfBoundsException e) { 
    break; 
    } 
} 

(j'ignore le IOException ici, comme vous avoir dans les 3 premiers exemples - il doit être manipulé mais vous écrivez le code, donc il n'est pas pertinent à la différence entre les 4 versions en termes de quantité de code).

Comparez cela au code équivalent d'approche 2 (le plus proche équivalent):

int bytesRead; 
while ((bytesRead = input.read(buffer)) != -1) { 
    output.write(buffer, 0, bytesRead); 
} 

Ce qui est beaucoup plus concis. Mais, comme je l'ai déjà mentionné, la brièveté du code n'est pas vraiment une mesure de la qualité du code, donc en soi, ce n'est pas une raison pour rejeter la version proposée pour le moment. Cependant, il y a des raisons plus fondamentales pourquoi il est pas une bonne approche ...


Dans le code proposé, il existe deux types d'exception prévus: IOException et ArrayIndexOutOfBoundsException. Ce sont des exceptions de nature fondamentalement différente: (est ce qui est une condition réelle exceptionnelle, et donc une utilisation appropriée d'une exception)

  • Le IOException devrait résulter d'une lecture ou d'écriture ne.

    IOException est une vérifiée exception. Les exceptions vérifiées doivent être gérées (il s'agit d'une erreur de compilation). Ils sont conçus pour indiquer des conditions et des conditions récupérables qui échappent au contrôle de l'API. Par exemple, si vous écrivez sur le disque ou le réseau, vous n'avez aucun contrôle sur le remplissage du disque par un autre processus, ou si les entrepreneurs qui creusent la route sont sur le point de couper votre connexion fibre. Les exceptions cochées indiquent "cela peut réussir si vous réessayez plus tard" (lorsque le disque n'est pas aussi plein, ou que les fournisseurs ont réparé la fibre)

  • Le ArrayIndexOutOfBoundsException devrait provenir de la fin du flux d'entrée (ce qui n'est pas une condition exceptionnelle, puisque pratiquement tous les flux se terminent, et donc n'est pas une utilisation appropriée d'une exception, ni une utilisation nécessaire d'une exception, puisqu'elle est détectable via les valeurs de retour de read).

    ArrayIndexOutOfBoundsException est une exception non vérifiée, qui résulte d'une erreur de programmation - utilisant l'API d'une manière qu'elle n'est pas destinée à être utilisée. Les exceptions non contrôlées n'ont pas besoin d'être gérées (ce n'est pas une erreur de compilation si vous ne le faites pas) car elles sont conçues pour indiquer des conditions irrécupérables, comme des erreurs de programmation. Par exemple, si vous essayez d'exécuter du code avec une entrée particulière et que vous lancez une exception non vérifiée à cause d'un bogue de programmation, il lancera la même exception non vérifiée plus tard car il exécute le même code.

En tant que tel, alors que vous pouvez attraper et récupérer des exceptions non vérifiées, qui est pas ce qu'ils ont été conçus pour (ce qui est la raison pour laquelle vous n'avez pas ont à). Il est plus facile d'écrire le code afin que l'exception ne se produise pas en premier lieu.

Et c'est facile dans ce cas: l'Javadoc for OutputStream dit:

Si off est négatif ou len est négatif ou off+len est supérieure à la longueur du tableau b, puis un IndexOutOfBoundsException est jeté.

Donc, répondez à ces conditions, et vous n'avez pas à vous en inquiéter.

(Et vous devez avoir été attraper IndexOutOfBoundsException au lieu de ArrayIndexOutOfBoundsException de toute façon, parce que certaines implémentations de OutputStream ne peuvent pas jeter ce dernier.)

Mais il y a une raison plus profonde pour laquelle vous ne devriez pas compter sur la capture exceptions non contrôlées pour votre flux de contrôle: vous pourriez ne pas détecter la condition que vous pensez être.

Une exception non contrôlée de tout type peut être jeté partout dans la chaîne d'appel d'un appel particulier - vous pourriez attendre qu'il se produit parce que OutputStream.write n'aime pas un paramètre len négatif, mais il peut réellement être appelé par n'importe quoi d'autre dans OutputStream.write - ou dans InputStream.read - ou dans l'une des autres méthodes qu'ils appellent transitif - vous ne pouvez pas dire avec certitude (sans inspecter la trace de la pile, mais les détails de ce que vous devez inspecter la trace de la pile car ils sont spécifiques à la mise en œuvre, et il faudrait donc beaucoup d'efforts pour que cela soit suffisamment robuste). Si vous traitez cette exception comme signifiant que vous avez atteint la fin du flux, vous risquez en fait de masquer un autre problème dans le code que vous voulez connaître. Donc, la meilleure chose à faire est d'écrire votre code de façon à ce que ne se base pas sur pour attraper une exception non vérifiée spécifique. Lorsqu'il est documenté qu'il va lancer une telle exception dans des circonstances spécifiques, éviter ces circonstances.