Java에서 파일을 바이트로 []


757

어떻게 변환합니까 java.io.FileA를 byte[]?


내가 생각할 수있는 한 가지 용도는 파일에서 직렬화 된 객체를 읽는 것입니다.
— Mahm00d

2
다른 하나는 헤더를 사용하여 파일 형식을 찾는 것입니다.
— James P.

이 byte [] bytes = null; BufferedInputStream fileInputStream = null; try {File file = 새 파일 (filePath); fileInputStream = 새로운 버퍼 입력 스트림 (새로운 파일 입력 스트림 (파일)); // fileInputStream = Thread.currentThread (). getContextClassLoader (). getResourceAsStream (this.filePath); 바이트 = 새로운 바이트 [(int) file.length ()]; fileInputStream.read (bytes); } catch (FileNotFoundException ex) {throw ex; }
— Rohit Chaurasiya

답변:


486

그것은 당신에게 가장 좋은 방법에 달려 있습니다. 생산성면에서는 휠을 재발 명하지 말고 Apache Commons를 사용하십시오. 어느 것이 여기에 있습니다 IOUtils.toByteArray(InputStream input).


29
@ ymajoros : 사실이야! 차라리 다른 종속성보다 코드 줄이 더 필요합니다. 종속성에는 숨겨진 비용이 있습니다. 해당 라이브러리를 최신 상태로 유지하고 빌드 스크립팅 등에 종속성을 포함하고 코드 등을 사용하여 사람들과 의사 소통하십시오. 이미 사용하는 것보다 코드가있는 라이브러리를 사용하고 있다면 otherwsie 직접 작성하십시오.
— Stijn de Witt

11
이것은 파일을 읽는 방법에 대한 질문이지만 java.IO.File 유형의 객체를 byte []로 변환하는 방법에 대한 질문에는 대답하지 않습니다.
— Ingo

5
어떻게 이런 일이를 읽는 데 사용됩니다 File에 byte[]? Java6를 사용하고 있으므로 NIO 메소드를 사용할 수 없습니다. (
— PASTRY

4
@ymajoros는 "표준 3 라인 솔루션"을 우리와 친절하게 공유하길 바랍니다. 따라서 휠 의존성에 의존 할 필요가 없습니까?
— matteo

3
@ matteo : 뭐요? Files.readAllBytes ()와 같은 다른 답변을 참조하십시오. 간단하고 의존성이 없습니다.
— ymajoros

1292

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

10
나는 File 객체가 아닌 (HTTP POST를 요청에서) 경로가
— aldo.roman.nurena

81
@ aldo.roman.nurena JDK7은 Path Object를 제공하는 File.toPath () 메소드를 도입했습니다.
— KevinL

6
파일에서 경로를 얻을 수 있습니다. 시도 : 파일 파일 = 새 파일 ( "/ 경로"); 경로 경로 = Paths.get (file.getAbsolutePath ()); byte [] data = Files.readAllBytes (경로);
— gfelisberto

2
java.nio에서 파일 닫기는 어떻게 처리됩니까? 즉, 위의 코드가 무언가를 닫아야합니까?
— akauppi

4
@akauppi 대답에있는 링크를 참조하십시오 : "파일이 닫혀 있는지 메소드 보장하지만 ..."
— 베른하르트 바커에게

226

JDK 7부터-하나의 라이너 :

byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));

외부 의존성이 필요하지 않습니다.


13
이것은 이제 Apache Commons가 필요한 허용 된 답변보다 더 나은 선택입니다.
— james.garriss

1
고마워 :) 나는 이것 또한 필요했다 : String text = new String (Files.readAllBytes (new File ( "/ path / to / file"). toPath ()));
— 출처

5
안드로이드에서는 최소 API 레벨이 26이어야합니다.
— Ashutosh Chamoli

2
당신은 추가해야합니다 import java.nio.file.Files;그리고 import java.nio.file.Paths;당신이 이미하지 않은 경우.
— Sam

164
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 ()의 반환 값을 확인해야합니다. 때때로 전체 파일을 읽지 못할 수도 있습니다.
— bugs_

8
이러한 상황은 파일을 읽는 동안 파일이 변경되는 경우에만 발생할 수 있습니다. 다른 모든 경우에는 IOException이 발생합니다. 이 문제를 해결하려면 파일을 읽기 / 쓰기 모드로 열 것을 제안합니다. RandomAccessFile (fileName, "rw")
— Dmitry Mitskevich 10

5
파일의 일부만 읽는 다른 소스 (파일은 네트워크 공유에 있습니다 ...) readFully ()는 당신이 찾고있는 계약을 가지고 있다고 상상할 수 있습니다.
— DThought

3
RandomAccessFile은 스레드로부터 안전하지 않습니다. 따라서 경우에 따라 동기화가 필요할 수 있습니다.
— bancer

@DmitryMitskevich 파일 시스템에 적합하지 않은 다른 경우도 있습니다. 예를 들어 리눅스에서 / proc /에서 "파일"을 읽으면 짧은 읽기 (즉, 모든 것을 읽으려면 루프가 필요함)
— nos

78

기본적으로 메모리에서 읽어야합니다. 파일을 열고 배열을 할당 한 후 파일에서 배열로 내용을 읽습니다.

가장 간단한 방법은 다음과 유사합니다.

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).


시도 밖에서 ios를 선언해야 함
— Daryl Spitzer

두 번째 예의 "ios.read (buffer)"문은 파일의 처음 4096 바이트에서만 읽습니다 (첫 번째 예에서 사용 된 것과 동일한 4k 버퍼로 가정). 두 번째 예제가 작동하려면 읽기가 -1 (파일 끝에 도달)에 대한 결과를 확인하는 while 루프 안에 있어야한다고 생각합니다.
— Stijn de Witt

죄송합니다. 위의 설명을 무시하고 파일 길이에 대한 명령문 설정 버퍼를 놓치십시오. 아직도, 나는 첫 번째 예를 더 좋아합니다. 한 번에 전체 파일을 버퍼로 읽는 것은 확장 할 수 없습니다. 파일이 크면 메모리가 손상 될 위험이 있습니다.
— Stijn de Witt

"가장 간단한"방법은 리소스를 사용하여 시도하는 것입니다.
— Sina Madani 2016 년

시원하지만 조금 장황합니다.
— Sapphire_Brick

77

누군가가 말했듯이 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);
        ...
    }
}

23

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을 사용하는 것보다 두 배의 메모리를 사용하게됩니다.
— james

1
불행히도 MappedByteBuffer는 자동으로 해제되지 않습니다.
— Tom Hawtin-tackline

2
놀랍게도 새로운 예제에는 고전적인 예외 예외 처리 인 printStackTrace가 포함됩니다.
— 제임스

동의합니다 .. 이클립스가 사용하는 기본 항목입니다. 예외를 다시 던져야한다고 생각합니다!
— 아 미트

파일에서 byte []를 만들기 위해 nio를 벤치마킹했습니다. 직접 버퍼를 사용하는 것 외에는 실제로 두 배의 메모리가 필요합니다. 매우 큰 파일 (200M의 경우 버퍼 IO보다 약 2 배 빠름)이 더 빠르지 만 5M 정도의 파일에 대해서는 5 배가 빠지는 것 같습니다.
— Chaffers

22

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

발신자는 스트림을 닫을 책임이 있습니다.


21
// 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;
    }

또한 루프 안에 numRead를 넣습니다. 가능한 가장 작은 유효 범위에서 변수를 선언하십시오. while 루프 외부에 두는 것은 복잡한 "while"테스트를 가능하게하기 위해서만 필요합니다. 루프 내부에서 EOF 테스트를 수행하는 것이 좋습니다 (발생하는 경우 EOFException 발생).
— erickson

throw new IOException("File is too large!");파일이 너무 클 때 어떻게해야합니까? 그것에 대한 예가 있습니까?
— Fer

21

간단한 방법 :

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

이미 언급 된 단일 라이너와 같은 더 간단한 방법이 있습니다.
— Sapphire_Brick

@Sapphire_Brick 더 간단한 방법은 그렇습니다. 그러나 하나의 라이너가 모든 상황에 맞지는 않습니다. 안드로이드와 같은.
— Behr

17

파일에서 바이트를 읽는 가장 간단한 방법

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

1
나는 "가장 간단한 방법"이라고 주장합니다 :)
— BlondCode

여기서 설명해 주시겠습니까? 왜 논쟁이 있습니까?
— Muhammad Sadiq

3
특별한 것은 없지만 가장 간단하게 말하면 더 간단한 해결책을 볼 수 있습니다.-> 제 생각에는 가장 간단하지 않습니다. 아마 몇 년 전 일지 모르지만 세상은 변하고 있습니다. 나는 그런 진술로 내 자신의 솔루션에 레이블을 붙이지 않을 것입니다. ;) 만약 당신이 "내 생각으로는 가장 간단한 것이 .."또는 "내가 찾은 가장 간단한 것"이라고 쓴다면, 당신을 귀찮게하고 싶지 않다.
— BlondCode

@ MuhammadSadiq : 아무것도 가져 오지 마십시오 .*, 나쁜 습관으로 간주됩니다.
— 사파이어

13

Guava는 Files.toByteArray () 를 제공합니다. 몇 가지 장점이 있습니다.

  1. 파일이 길이가 0을보고하지만 여전히 내용을 가지고있는 코너 케이스를 다룹니다.
  2. 파일을로드하려고 시도하기 전에 큰 파일을 읽으려고하면 OutOfMemoryException이 발생합니다. (file.length ()의 영리한 사용을 통해)
  3. 바퀴를 재발 명할 필요는 없습니다.

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

어떤 JDK 레벨입니까?
— Jonathan S. Fisher

11

커뮤니티 위키 답변과 동일한 접근 방식을 사용하지만 깨끗하고 즉시 사용 가능 (Android에서 Apache Commons 라이브러리를 가져 오지 않으려는 경우 선호되는 접근 방식) :

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

8

나는 이것이 가장 쉬운 방법이라고 믿습니다.

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

7
2009 년 Tom의 제안에 대한 답변이 이미 있습니다
— Knut Herrmann

7

ReadFully 현재 파일 포인터에서 시작하여이 파일에서 바이트 배열로 b.length 바이트를 읽습니다. 이 메소드는 요청 된 바이트 수를 읽을 때까지 파일에서 반복적으로 읽습니다. 이 메소드는 요청 된 바이트 수를 읽거나 스트림의 끝이 감지되거나 예외가 발생할 때까지 차단합니다.

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

5

미리 할당 된 바이트 버퍼로 바이트를 읽으려면이 답변이 도움이 될 수 있습니다.

당신의 첫 번째 추측은 아마 사용하는 것입니다 InputStream read(byte[]). 그러나이 방법에는 결함이있어 사용하기가 부적절합니다. EOF가 발생하지 않더라도 어레이가 실제로 완전히 채워질 것이라는 보장은 없습니다.

대신을 살펴보십시오 DataInputStream readFully(byte[]). 이것은 입력 스트림의 래퍼이며 위에서 언급 한 문제가 없습니다. 또한이 방법은 EOF가 발생하면 발생합니다. 훨씬 좋습니다.


4

다음과 같은 방법으로 java.io.File을 byte []로 변환 할뿐만 아니라 서로 다른 여러 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

타사 라이브러리를 사용하지 않고 다른 솔루션을 추가하겠습니다. Scott 이 제안한 예외 처리 패턴을 재사용합니다 ( link ). 그리고 추한 부분을 별도의 메시지로 옮겼습니다 (일부 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;
}

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

속이 빈 캐치 블록을 사용하지 마십시오. 디버깅을 어렵게 만듭니다.
— Sapphire_Brick

1
//The file that you wanna convert into byte[]
File file=new File("/storage/0CE2-EA3D/DCIM/Camera/VID_20190822_205931.mp4"); 

FileInputStream fileInputStream=new FileInputStream(file);
byte[] data=new byte[(int) file.length()];
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
bufferedInputStream.read(data,0,data.length);

//Now the bytes of the file are contain in the "byte[] data"

1
이 코드는 질문에 대한 해결책을 제공 할 수 있지만 왜 / 어떻게 작동하는지에 대한 컨텍스트를 추가하는 것이 좋습니다. 이것은 미래의 사용자가 배우고 그 지식을 자신의 코드에 적용하는 데 도움이 될 수 있습니다. 또한 코드를 설명 할 때 사용자의 의견을 공감 형태로 긍정적 인 피드백을받을 가능성이 있습니다.
— borchvm

글쎄, 그것은 미래의 게시물에서 명심해야 할 중요한 부분입니다. 유용한 통찰력에 감사드립니다.
— 우 사마 Mehmood

0

이 시도 :

import sun.misc.IOUtils;
import java.io.IOException;

try {
    String path="";
    InputStream inputStream=new FileInputStream(path);
    byte[] data=IOUtils.readFully(inputStream,-1,false);
}
catch (IOException e) {
    System.out.println(e);
}

다른 JRE에서 실행될 경우 앱을 중단시키는 특정 JRE 구현이 필요합니다.
— rattaman

2
작은 실수는 : :) IOException이 아닌 IOException이 있지만, 덕분에
— 마탄 마르시 아노

1
@MatanMarciano : 내 나쁜
— 사파이어

-7

에서 JDK8

Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();

2
프랑스어를 사용하는 친구의 질문을 읽고 "byte []"로 변환하는 것에 대해 질문하지만 답변에서 제공하지 않습니다.
— Kaiser Keister

2
이것은 byte []로 변환하기위한 원격 옵션을 제공하지 않습니다!
— Anddo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.