Файл в байт[] в Java

Как преобразовать java.io.File до byte[]?

21 ответов


Это зависит от того, что лучше всего означает для вас. Продуктивность мудрая, не изобретайте колесо и не используйте Apache Commons. Который здесь IOUtils.toByteArray(InputStream input).


С JDK 7 можно использовать Files.readAllBytes(Path).

пример:

import java.io.File;
import java.nio.file.Files;

File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());

import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);

документация для Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html


начиная с JDK 7 - One liner:

byte[] array = Files.readAllBytes(new File("/path/to/file").toPath());

внешние зависимости не требуются.


в общем, вы должны прочитать его в память. Откройте файл, выделите массив и прочитайте содержимое из файла в массив.

самый простой способ - что-то похожее на это:

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1) {
            ous.write(buffer, 0, read);
        }
    }finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
        }

        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return ous.toByteArray();
}

это имеет некоторое ненужное копирование содержимого файла (на самом деле данные копируются три раза: из файла в buffer С buffer to ByteArrayOutputStream С ByteArrayOutputStream к фактическому результирующему массиву).

Вам также нужно убедиться, что Вы читаете только в памяти файлы до определенного размера (обычно это зависит от приложения): -).

Вам также нужно обработать IOException вне функции.

другой способ-это:

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }

    byte[] buffer = new byte[(int) file.length()];
    InputStream ios = null;
    try {
        ios = new FileInputStream(file);
        if (ios.read(buffer) == -1) {
            throw new IOException(
                    "EOF reached while trying to read the whole file");
        }
    } finally {
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return buffer;
}

это не имеет ненужного копирования.

FileTooBigException является исключением пользовательского приложения. The MAX_FILE_SIZE константы-это параметры приложения.

для больших файлов вы, вероятно, должны думать алгоритм обработки потока или использовать отображение памяти (см. java.nio).


как кто-то сказал:Apache Commons Файл Utils возможно, то, что вы ищете

public static byte[] readFileToByteArray(File file) throws IOException

пример использования (Program.java):

import org.apache.commons.io.FileUtils;
public class Program {
    public static void main(String[] args) throws IOException {
        File file = new File(args[0]);  // assume args[0] is the path to file
        byte[] data = FileUtils.readFileToByteArray(file);
        ...
    }
}

вы также можете использовать api NIO для этого. Я мог бы сделать это с помощью этого кода, пока общий размер файла (в байтах) будет соответствовать int.

File f = new File("c:\wscp.script");
FileInputStream fin = null;
FileChannel ch = null;
try {
    fin = new FileInputStream(f);
    ch = fin.getChannel();
    int size = (int) ch.size();
    MappedByteBuffer buf = ch.map(MapMode.READ_ONLY, 0, size);
    byte[] bytes = new byte[size];
    buf.get(bytes);

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} finally {
    try {
        if (fin != null) {
            fin.close();
        }
        if (ch != null) {
            ch.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Я думаю, что это очень быстро, так как его использование MappedByteBuffer.


// Returns the contents of the file in a byte array.
    public static byte[] getBytesFromFile(File file) throws IOException {        
        // Get the size of the file
        long length = file.length();

        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
            // File is too large
            throw new IOException("File is too large!");
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;

        InputStream is = new FileInputStream(file);
        try {
            while (offset < bytes.length
                   && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
                offset += numRead;
            }
        } finally {
            is.close();
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }
        return bytes;
    }

Если у вас нет Java 8, и согласитесь со мной, что включение массивной библиотеки, чтобы избежать написания нескольких строк кода, - плохая идея:

public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] b = new byte[1024];
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    int c;
    while ((c = inputStream.read(b)) != -1) {
        os.write(b, 0, c);
    }
    return os.toByteArray();
}

вызывающий отвечает за закрытие потока.


простой способ сделать это:

File fff = new File("/path/to/file");
FileInputStream fileInputStream = new FileInputStream(fff);

// int byteLength = fff.length(); 

// In android the result of file.length() is long
long byteLength = fff.length(); // byte count of the file-content

byte[] filecontent = new byte[(int) byteLength];
fileInputStream.read(filecontent, 0, (int) byteLength);

самый простой способ чтения байтов из файла

import java.io.*;

class ReadBytesFromFile {
    public static void main(String args[]) throws Exception {
        // getBytes from anyWhere
        // I'm getting byte array from File
        File file = null;
        FileInputStream fileStream = new FileInputStream(file = new File("ByteArrayInputStreamClass.java"));

        // Instantiate array
        byte[] arr = new byte[(int) file.length()];

        // read All bytes of File stream
        fileStream.read(arr, 0, arr.length);

        for (int X : arr) {
            System.out.print((char) X);
        }
    }
}

гуава имеет файлы.toByteArray() предлагаем вам. Он имеет несколько преимуществ:

  1. он охватывает угловой случай, когда файлы сообщают длину 0, но все еще имеют контент
  2. он сильно оптимизирован, вы получаете исключение OutOfMemoryException, если пытаетесь прочитать в большом файле, прежде чем даже пытаться загрузить файл. (Благодаря умному использованию файла.length ())
  3. вам не нужно изобретать колесо.

используя тот же подход, что и ответ сообщества wiki, но более чистый и компилируемый из коробки (предпочтительный подход, если вы не хотите импортировать библиотеки Apache Commons, например, на Android):

public static byte[] getFileBytes(File file) throws IOException {
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1)
            ous.write(buffer, 0, read);
    } finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
    }
    return ous.toByteArray();
}

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

File file = getYourFile();
Path path = file.toPath();
byte[] data = Files.readAllBytes(path);

Я считаю, что это самый простой способ:

org.apache.commons.io.FileUtils.readFileToByteArray(file);

ReadFully читает b.длина байтов из этого файла в массив байтов, начиная с указателя текущего файла. Этот метод считывает повторно из файла до тех пор, пока не будет считано запрошенное количество байтов. Этот метод блокируется до тех пор, пока не будет прочитано запрошенное количество байтов, не будет обнаружен конец потока или не будет создано исключение.

RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);

позвольте мне добавить еще одно решение без использования сторонних библиотек. Он повторно использует шаблон обработки исключений, предложенный Скотт (ссылке). И я переместил уродливую часть в отдельное сообщение (Я бы спрятался в каком-то классе FileUtils ;) )

public void someMethod() {
    final byte[] buffer = read(new File("test.txt"));
}

private byte[] read(final File file) {
    if (file.isDirectory())
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is a directory");
    if (file.length() > Integer.MAX_VALUE)
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is too big");

    Throwable pending = null;
    FileInputStream in = null;
    final byte buffer[] = new byte[(int) file.length()];
    try {
        in = new FileInputStream(file);
        in.read(buffer);
    } catch (Exception e) {
        pending = new RuntimeException("Exception occured on reading file "
                + file.getAbsolutePath(), e);
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) {
                if (pending == null) {
                    pending = new RuntimeException(
                        "Exception occured on closing file" 
                             + file.getAbsolutePath(), e);
                }
            }
        }
        if (pending != null) {
            throw new RuntimeException(pending);
        }
    }
    return buffer;
}

Если вы хотите прочитать байты в предварительно выделенный байтовый буфер, этот ответ может помочь.

ваша первая догадка, вероятно, будет использовать InputStream read(byte[]). Однако этот метод имеет недостаток, который делает его неоправданно сложным в использовании: нет никакой гарантии, что массив действительно будет полностью заполнен, даже если EOF не встречается.

вместо этого взгляните на DataInputStream readFully(byte[]). Это оболочка для входных потоков и не имеет вышеупомянутого вопрос. Кроме того этот метод вызывает при обнаружении EOF. Намного приятнее.


public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] buffer = new byte[32 * 1024];
    int bufferSize = 0;
    for (;;) {
        int read = inputStream.read(buffer, bufferSize, buffer.length - bufferSize);
        if (read == -1) {
            return Arrays.copyOf(buffer, bufferSize);
        }
        bufferSize += read;
        if (bufferSize == buffer.length) {
            buffer = Arrays.copyOf(buffer, bufferSize * 2);
        }
    }
}

другой способ чтения байтов из файла

Reader reader = null;
    try {
        reader = new FileReader(file);
        char buf[] = new char[8192];
        int len;
        StringBuilder s = new StringBuilder();
        while ((len = reader.read(buf)) >= 0) {
            s.append(buf, 0, len);
            byte[] byteArray = s.toString().getBytes();
        }
    } catch(FileNotFoundException ex) {
    } catch(IOException e) {
    }
    finally {
        if (reader != null) {
            reader.close();
        }
    }

не только следующий способ преобразует java.Ио.Файл в байт [], я также обнаружил, что это самый быстрый способ чтения в файле, при тестировании многих разных методы чтения файлов Java друг против друга:

java.НИО.файл.Файлы.readAllBytes()

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

public class ReadFile_Files_ReadAllBytes {
  public static void main(String [] pArgs) throws IOException {
    String fileName = "c:\temp\sample-10KB.txt";
    File file = new File(fileName);

    byte [] fileBytes = Files.readAllBytes(file.toPath());
    char singleChar;
    for(byte b : fileBytes) {
      singleChar = (char) b;
      System.out.print(singleChar);
    }
  }
}