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

594

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

  • 0
    Одно из возможных применений - чтение сериализованных объектов из файла.
  • 2
    Другой - найти тип файла с помощью заголовка.
Теги:
file-io

23 ответа

394
Лучший ответ

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

  • 7
    с учетом приведенных ниже примеров, а также с точки зрения правильности ...
  • 21
    @ymajoros: так правда! Я предпочел бы иметь несколько дополнительных строк кода, чем еще одну зависимость. Зависимости имеют скрытые затраты. Вы должны быть в курсе этой библиотеки, включать зависимости в свои сценарии сборки и т. Д., Сообщать об этом людям, использующим ваш код и т. Д. И т. Д. Если вы уже используете библиотеку, в которой есть код, чем используйте ее, в противном случае, я бы сказал, напиши это сам.
Показать ещё 9 комментариев
1052

Из 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());
  • 6
    У меня есть объект File, а не путь (из http post запроса)
  • 74
    @ aldo.roman.nurena JDK7 представил метод File.toPath (), который даст вам объект Path.
Показать ещё 8 комментариев
150
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

  • 2
    Вы должны проверить возвращаемое значение f.read (). Иногда может случиться так, что вы не будете читать весь файл.
  • 8
    Такая ситуация может возникнуть, только если файл изменяется во время чтения. Во всех остальных случаях IOException выбрасывается. Для решения этой проблемы я предлагаю открыть файл в режиме чтения-записи: RandomAccessFile (fileName, "rw")
Показать ещё 5 комментариев
148

Так как JDK 7 - один вкладыш:

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

Никаких внешних зависимостей не требуется.

  • 9
    Теперь это лучший выбор, чем принятый ответ, который требует Apache Commons.
  • 0
    Спасибо :) Мне также был нужен этот: String text = new String (Files.readAllBytes (new File ("/ path / to / file"). ToPath ())); который изначально от stackoverflow.com/a/26888713/1257959
Показать ещё 2 комментария
75

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

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

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 до 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 является специальным исключением. Константа MAX_FILE_SIZE - это параметры приложения.

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

  • 0
    IOS должен быть объявлен вне попытки
  • 0
    Один пример с java.nio для больших файлов был бы хорош.
Показать ещё 3 комментария
70

Как кто-то сказал, Apache Commons File 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);
        ...
    }
}
22

Вы также можете использовать NIO api, чтобы сделать это. Я мог бы сделать это с помощью этого кода, если общий размер файла (в байтах) будет соответствовать 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.

  • 2
    абсолютно не нужно использовать отображение памяти, если вы собираетесь прочитать файл только один раз, и в итоге он будет использовать вдвое больше памяти, чем обычный FileInputStream.
  • 1
    К сожалению, MappedByteBuffer не выпускается автоматически.
Показать ещё 4 комментария
19
// 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;
    }
  • 0
    Кроме того, поместите numRead внутри цикла. Объявите переменные в наименьшей допустимой области видимости. Помещение его вне цикла while необходимо только для включения этого сложного теста «while»; было бы лучше сделать тест на EOF внутри цикла (и выбросить EOFException, если это произойдет).
  • 0
    throw new IOException("File is too large!"); что делать, если файл слишком большой? Есть ли еще пример?
17

Если у вас нет 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();
}

Caller отвечает за закрытие потока.

14

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

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);
12

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

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);
        }
    }
}
  • 0
    Я спорю о том, чтобы быть "Простейшим путем" :)
  • 0
    Можете ли вы объяснить здесь? Почему вы спорите?
Показать ещё 1 комментарий
11

В Guava есть Files.toByteArray(), чтобы предложить вам. Он имеет несколько преимуществ:

  • Он охватывает угловой случай, когда файлы сообщают о длине 0, но имеют контент
  • Он сильно оптимизирован, вы получаете исключение OutOfMemoryException, если пытаетесь прочитать в большом файле, прежде чем пытаться загрузить файл. (Благодаря умному использованию file.length())
  • Вам не нужно изобретать велосипед.
9
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);
  • 0
    Что это за уровень JDK?
  • 0
    java.nio существует с Java 1.4, если это отвечает на ваш вопрос ...
9

Используя тот же подход, что и ответ сообщества, но более чистый и компилирующийся из коробки (предпочтительный подход, если вы не хотите импортировать Apache Commons libs, например, на 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();
}
7

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

org.apache.commons.io.FileUtils.readFileToByteArray(file);
  • 7
    уже есть ответ с этим предложением от Тома в 2009 году
5

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

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

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

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

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

3

Позвольте мне добавить другое решение без использования сторонних библиотек. Он повторно использует шаблон обработки исключений, который был предложен Scott (ссылка). И я переместил уродливую часть в отдельное сообщение (я бы спрятался в каком-то классе 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;
}
2
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);
        }
    }
}
1

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

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();
        }
    }
0

Попробуй это:

    try
    {
        String path="";

        InputStream inputStream=new FileInputStream(path);

        byte[] data=IOUtils.readFully(inputStream,-1,false);

    }
    catch (Exception e)
    {

    }

Не забудьте " импортировать sun.misc.IOUtils";

0

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

java.nio.file.Files.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);
    }
  }
}
-3

В JDK8

Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();
  • 0
    Прочитайте вопрос, мой франкоговорящий друг, он спрашивает о преобразовании в «байт []», а ваш ответ этого не дает.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню