Demo: pliki binarne

Poniżej przykład wykorzystania plików binarnych (klasa RAF) do przetwarzania liczb typu int oraz double. Do pobrania: projekt NetBeans w formacie zip.

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;
import java.io.RandomAccessFile;
import java.util.logging.Level;
import java.util.logging.Logger;

public class RAFDemo 
{
    static public void generujPlikInt()
    {
        Random gen = new Random();
        // Wylosuj ile liczb zapisać do pliku, ograniczmy zakres dla testów 
        int ileLiczb = gen.nextInt( 4 ) + 1;
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "int.bin", "rw" ) )
        {
            // Plik mógł istnieć, obcinamy go do pliku pustego.
            plik.setLength( 0 ); 
            
            int liczba;
            System.out.printf( "\nDo wygenerowania: %d\n", ileLiczb );
            
            while( ileLiczb > 0 )
            {    
                // Losowanie liczby
                liczba = gen.nextInt( 5 );
                // Zrzut kontrolny do stdout
                System.out.print( liczba + " " );
                // Zapis liczby do pliku
                plik.writeInt( liczba );

                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nWygenerowano plik o rozmiarze (bajty): %d", plik.length() );
            System.out.printf( "\nLiczba zawartych w nim liczb: %d\n", plik.length() / Integer.BYTES );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje nrLiczby nie udało się go utworzyć
            System.out.print( "Błąd tworzenia pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }
    
    static public void pokazPlikInt()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "int.bin", "r" ) )
        {
            long ileLiczb = plik.length() / Integer.BYTES;
            
            int liczba;
            System.out.printf( "\nDo przeczytania: %d\n", ileLiczb );
            
            while( ileLiczb > 0 )
            {    
                // Odczyt liczby z pliku
                liczba = plik.readInt();
                // Zrzut kontrolny do stdout
                System.out.print( liczba + " " );
                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nOdczytano plik o rozmiarze (bajty): %d", plik.length() );
            System.out.printf( "\nLiczba zawartych w nim liczb: %d\n", plik.length() / Integer.BYTES );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje 
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }

    static public void generujPlikIntDouble()
    {
        Random gen = new Random();
        // Wylosuj ile liczb zapisać do pliku, ograniczmy zakres dla testów 
        int ileLiczb = gen.nextInt( 10 ) + 1;
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "intdouble.bin", "rw" ) )
        {
            // Plik mógł istnieć, obcinamy go do pliku pustego.
            plik.setLength( 0 ); 
            
            int liczbaInt;
            double liczbaDouble;
            System.out.printf( "\nDo wygenerowania: %d\n", ileLiczb );
            
            while( ileLiczb > 0 )
            {    
                // Losowanie liczby int
                liczbaInt = gen.nextInt( 5 );
                // Zrzut kontrolny do stdout
                System.out.print( liczbaInt + " " );
                // Zapis liczby do pliku
                plik.writeInt( liczbaInt );
                // Losowanie liczby double
                liczbaDouble = gen.nextDouble();
                // Zrzut kontrolny do stdout
                System.out.print( liczbaDouble + " | " );
                // Zapis liczby do pliku
                plik.writeDouble( liczbaDouble );

                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nWygenerowano plik o rozmiarze (bajty): %d", plik.length() );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istniej nrLiczby nie udało się go utworzyć
            System.out.print( "Błąd tworzenia pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Błąd dostępu do pliku." );
        }
    }
    
    static public void pokazPlikIntDouble()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "intdouble.bin", "r" ) )
        {
            long ileLiczb = plik.length() / ( Integer.BYTES + Double.BYTES );
            
            int liczbaInt;
            double liczbaDouble;
            
            System.out.printf( "\nDo przeczytania: %d\n", ileLiczb );
            
            while( ileLiczb > 0 )
            {    
                // Odczyt liczby int z pliku
                liczbaInt = plik.readInt();
                // Zrzut kontrolny do stdout
                System.out.print( liczbaInt + " " );
                // Odczyt liczby int z pliku
                liczbaDouble = plik.readDouble();
                // Zrzut kontrolny do stdout
                System.out.print( liczbaDouble + " | " );
                
                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nOdczytano plik o rozmiarze (bajty): %d", plik.length() );
            System.out.printf( "\nLiczba zawartych w nim liczb: %d\n", plik.length() / ( Integer.BYTES + Double.BYTES ) );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje 
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }

    static public void sumaLiczbZPlikuInt()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "int.bin", "r" ) )
        {
            long ileLiczb = plik.length() / Integer.BYTES;
            
            long suma = 0;
            
            while( ileLiczb > 0 )
            {    
                // Odczyt liczby int z pliku nrLiczby dopisanie do sumy
                suma += plik.readInt();
                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nSuma liczb %d", suma );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }
    
    static public void sumaCoDrugiejLiczbyZPlikuInt()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "int.bin", "r" ) )
        {
            // Czytamy połowę liczb
            long ileLiczb = ( plik.length() / Integer.BYTES ) / 2;
            
            long suma = 0;
            
            while( ileLiczb > 0 )
            {    
                // Odczyt liczby int z pliku nrLiczby dopisanie do sumy
                suma += plik.readInt();
                // Przeskoczenie kolejnej liczby całkowitej
                plik.seek( plik.getFilePointer() + Integer.BYTES );
                --ileLiczb;
            }
            // Komunikaty kontrolne
            System.out.printf( "\nSuma liczb %d", suma );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }
    static public void sumaIntZPlikuIntDouble()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "intdouble.bin", "r" ) )
        {
            long ileLiczb = plik.length() / ( Integer.BYTES + Double.BYTES );
            
            long suma = 0;
 
            while( ileLiczb > 0 )
            {    
                // Odczyt liczby int z pliku nrLiczby połączenie do sumy
                suma += plik.readInt();
                // Przeskoczenie liczby double
                plik.seek( plik.getFilePointer() + Double.BYTES );
                
                --ileLiczb;
            }
            System.out.printf( "\nSuma liczb całkowitych: %d", suma );
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje 
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }

    static public void odwrocLiczbyCalkowite()
    {
        // Try-with-resource, plik zostanie zamknięty niezależnie od 
        // tego, czy blok try wykona się z powodzeniem czy wystąpi w nim wyjątek.
        try( RandomAccessFile plik = new RandomAccessFile( "int.bin", "rw" ) )
        {
            long dlugosc = plik.length();
            long ileDoZmiany = ( plik.length() / Integer.BYTES ) / 2;
       
            // Zamieniamy od początku do połowy, skacząc początek koniec
            for( int nrLiczby = 0; nrLiczby < ileDoZmiany; ++nrLiczby )
            {
               // Liczba z początku nrLiczby liczba z końca
               int buforP, buforK;
               
               // Odczyt liczb, najpierw skok na początek
               plik.seek( nrLiczby * Integer.BYTES );
               buforP = plik.readInt();

               // Teraz skok na koniec
               plik.seek( dlugosc - ( nrLiczby + 1 ) * Integer.BYTES );
               buforK = plik.readInt();

               // Zapis liczb też skok na początek nrLiczby koniec 
               plik.seek( nrLiczby * Integer.BYTES );
               plik.writeInt( buforK );
               plik.seek( dlugosc - ( nrLiczby + 1 ) * Integer.BYTES );
               plik.writeInt( buforP );
            } 
        } 
        catch( FileNotFoundException ex ) 
        {
            // Tu trafiamy, gdy plik nie istnieje 
            System.out.print( "Błąd pliku." );
        }
        catch( IOException ex ) 
        {
            // Tu trafiamy, gdy nastąpił błąd operacji związanej z plikiem
            System.out.print( "Bład dostępu do pliku." );
        }
    }
    
    static public void pokazMenu()
    {
        System.out.print( "\n 1. Generuj plik liczb całkowitych" );
        System.out.print( "\n 2. Pokaż zawartość pliku liczb całkowitych" );
        System.out.print( "\n 3. Generuj plik liczb całkowitych i rzeczywistych" );
        System.out.print( "\n 4. Pokaż zawartość pliku liczb całkowitych i rzeczywistych" );
        System.out.print( "\n 5. Suma liczb z pliku liczb całkowitych" );
        System.out.print( "\n 6. Suma co drugiej liczby z pliku liczb całkowitych" );
        System.out.print( "\n 7. Suma lb całk. z pliku liczb całkowitych i rzeczywistych" );
        System.out.print( "\n 8. Suma lb rzecz. po parzystej lb. całkowitej (z pliku liczb całkowitych i rzeczywistych)" );
        System.out.print( "\n 9. Odwróć kolejność liczb w pliku liczb całkowitych" );
        System.out.print( "\n10. Odwróć kolejność liczb double w pliku liczb całkowitych i rzeczywistych" );
        System.out.print( "\n11. Jak 10 pod warunkiem, ale odwracamy liczbę rzecz. gdzy poprzedzająca liczba całk. jest dodatnia" );
        System.out.print( "\n 0. Koniec\n>> " );
    }
    
    public static void main(String[] args) 
    {
        int wybor;
        Scanner we = new Scanner( System.in );
        
        do
        {
            pokazMenu();
            switch( wybor = we.nextInt() )
            {
                case  1 : generujPlikInt();
                          break;
                case  2 : pokazPlikInt();
                          break;
                case  3 : generujPlikIntDouble();
                          break;
                case  4 : pokazPlikIntDouble();
                          break;
                case  5 : sumaLiczbZPlikuInt();
                          break;
                case  6 : sumaCoDrugiejLiczbyZPlikuInt();
                          break;
                case  7 : sumaIntZPlikuIntDouble();
                          break;
                case  8 : // Do zrobienia
                          ;
                          break;
                case  9 : odwrocLiczbyCalkowite();
                          break;
                case 10 : // Do zrobienia
                          ;
                          break;
                case 11 : // Do zrobienia
                          ;
                          break;
            }
        }
        while( wybor != 0 );
    }
    
}