11
votes

Comment créer des introuvoirs contraintes pour ne lire qu'une partie du fichier?

Je souhaite créer une intrigue qui est limitée à une certaine gamme d'octets dans le fichier, par ex. d'octets de la position 0 à 100. De sorte que le code client doit voir EOF une fois que 100e octet est atteint.


0 commentaires

7 Réponses :


10
votes

Le lue () méthode de introuvable lit un seul octet à la fois. Vous pouvez écrire une sous-classe de introuvable qui maintient un compteur interne; Chaque fois que lisez () est appelé, mettez à jour le compteur. Si vous avez frappé votre maximum, ne laissez aucune autre lecture (retour -1 ou quelque chose comme ça).

Vous devrez également vous assurer que les autres méthodes de lecture READ_INT , etc. sont non prises en charge (ex: les remplacer et simplement lancer une inception non prêtée ());

Je ne sais pas ce que votre cas d'utilisation est, mais en tant que bonus, vous pouvez également implémenter la mise en mémoire tampon.


2 commentaires

Je ne pense pas qu'il y ait besoin de mettre en œuvre la mise en mémoire tampon - c'est des préoccupations de mixage et la manière dont la lecture (octets []) fonctionne, renvoyant jusqu'à la quantité de données requise, rend cela inutile. Il est plus propre et tout aussi efficace pour envelopper le courant de base dans une bufferedInPutStream.


NB aussi que les seules méthodes d'introuvrete qui sont déclarées abstraites sont en lecture () et de lire (octets [], int, int), donc parfois, vous pouvez simplement définir ces 2 (plus peut-être fermer ()) dans votre classe enfant.



2
votes

Si vous n'avez besoin que de 100 octets, alors simples est probablement préférable, je les lirais dans un tableau et envelopper cela comme une byearrayInputStream. Par exemple xxx

si vous ne voulez pas utiliser datagnutretream.ralely , il y a ioutils.rafly de Apache Commons-io, ou Vous pouvez implément la boucle de lecture explicitement.

Si vous avez des besoins plus avancés, tels que la lecture d'un segment au milieu du fichier, ou des quantités plus importantes de données, puis extension d'introuvream et remplacer la lecture (octet [], int, int) ainsi que lire (), vous donnera une meilleure performance que de simplifier la méthode de lecture ().


0 commentaires

8
votes

comme Danben dit , décorer votre flux et appliquer la contrainte: xxx


1 commentaires

Réutilisation de code (limitedInputStream des Commons-io): COMMONS.APACHE.ORG/PROPER/COMMONS-IO/APIDOCS/ORG/APACHE/COMM ONS / ...



4
votes

1 commentaires

LimitInputStream doit être supprimé dans la version 15.0 de Guava. Utiliser bytestreeams.limit (java.io.inputtream, long) à la place.



2
votes

Vous pouvez utiliser Bytestreams de Guava. Notez que vous devez utiliser avec guide () avant la limite, par exemple:

ByteStreams.skipFully(tmpStream, range.start());
tmpStream = ByteStreams.limit(tmpStream, range.length());


0 commentaires

2
votes

En plus de Cette solution, à l'aide de la méthode code> Ignorer code> d'un InputStream code>, vous pouvez également lire une plage à partir du milieu du fichier.

public class RangeInputStream extends InputStream
{
    private InputStream parent;
    private long remaining;

    public RangeInputStream(InputStream parent, long start, long end) throws IOException
    {
        if (end < start)
        {
            throw new IllegalArgumentException("end < start");
        }

        if (parent.skip(start) < start)
        {
            throw new IOException("Unable to skip leading bytes");
        }

        this.parent=parent;
        remaining = end - start;
    }

    @Override
    public int read() throws IOException
    {
        return --remaining >= 0 ? parent.read() : -1;
    }
}


0 commentaires