2010-03-18 8 views
0

J'ai quelques fichiers JPG qui doivent être remplacés à l'exécution avec une version standard JFIF d'eux-mêmes (nous utilisons un fournisseur qui nous donne des fichiers JPG qui n'ont pas d'en-têtes appropriés pour certaines applications) ... Je suis en mesure de créer un nouveau fichier de l'image existante, puis obtenir une image en mémoire tampon à partir de ce fichier et écrire le contenu de retour dans le fichier sans avoir à le supprimer et il fonctionne ...Java/Groovy File IO Remplacement d'un fichier image avec son propre contenu - Pourquoi cela fonctionne-t-il?

imageSrcFolder.eachFileMatch (~/.*\.jpg/, { 
    BufferedImage bi = ImageIO.read(it) 
    ImageIO.write(bi, "jpg", it) 
}); 

la question J'ai pourquoi? Pourquoi le fichier ne finit-il pas doublé de taille? Pourquoi ne dois-je pas le supprimer en premier? Pourquoi suis-je capable de prendre un objet fichier dans un fichier existant et de le traiter comme si c'était un tout nouveau? Il semble que ce que je considère être un "fichier" n'est pas ce que l'objet File est réellement en java, sinon cela ne fonctionnerait pas du tout.

Mon code fait exactement ce que je veux faire, mais je ne suis pas convaincu que ce sera toujours ... il semble juste trop facile

Répondre

3

Le JavaDoc pour ImageIO.write comprend cette phrase:

Écrit une image à l'aide d'un ImageWriter arbitraire qui prend en charge le format donné à File. S'il y a déjà un File présent, son contenu est mis au rebut.

Cela suppose que it est un File, comme vous l'avez utilisé à la fois la lecture et d'écriture.

0

Vous avez raison: un objet File en Java ne fait pas référence à la même chose que vous pouvez penser lorsque vous entendez le mot "fichier", comme dans un document sur votre système de fichiers avec une certaine taille et contenu. C'est plus comme un chemin, et en fait les instances de File et les instances de la classe Path plus récente peuvent être librement converties les unes aux autres.

Une instance de fichier Java peut être considérée comme un pointeur vers un fichier. Le fichier hypothétique auquel il pointe peut ou peut ne pas exister. S'il existe, il pourrait s'agir d'un répertoire. Il n'est pas "ouvert" pour la lecture ou l'écriture jusqu'à ce que vous appeliez des fonctions fonctionnant sur l'instance File qui ouvre le fichier auquel il fait référence, par exemple new FileInputStream(file), et même alors l'occurrence File ne sait rien de cette poignée de fichier ouverte; seule la nouvelle instance de FileInputStream le fait.

Alors, ImageIO.read(...) ouvre le fichier, lit son contenu et le ferme finalement. ImageIO.write(...) est en train de supprimer le fichier ou de supprimer son contenu après l'avoir ouvert, puis en y écrivant et enfin en le fermant. Ils fonctionnent tous les deux sur la même instance de fichier et continuent à pointer vers le même chemin de fichier, mais le fichier de ce chemin peut être complètement différent par la suite.