Nasıl dönüştürebilirim java.io.File
a byte[]
?
Nasıl dönüştürebilirim java.io.File
a byte[]
?
Yanıtlar:
Sizin için en iyi ne anlama geldiğine bağlıdır. Verimlilik açısından, tekerleği yeniden icat etmeyin ve Apache Commons kullanın. Hangisi burada IOUtils.toByteArray(InputStream input)
.
File
için byte[]
? Java6 kullanıyorum, bu yüzden NIO yöntemlerini kullanamıyorum :(
Gönderen JDK 7 kullanabilirsinizFiles.readAllBytes(Path)
.
Misal:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
JDK 7'den beri - bir astar:
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));
Harici bağımlılık gerekmez.
import java.nio.file.Files;
ve import java.nio.file.Paths;
henüz yapmadıysanız.
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Java 8 belgeleri: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
Temelde onu bellekte okumak zorundasınız. Dosyayı açın, diziyi ayırın ve içeriği dosyadan diziye okuyun.
En basit yol buna benzer bir şeydir:
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();
}
Bu dosya içeriğinin bazı gereksiz kopyalama (: dosyadan aslında veri üç kez kopyalanır vardır buffer
, gelen buffer
için ByteArrayOutputStream
gelen ByteArrayOutputStream
fiili çıkan dizi).
Ayrıca, bellekte yalnızca belirli bir boyuta kadar olan dosyaları okuduğunuzdan emin olmanız gerekir (bu genellikle uygulamaya bağlıdır) :-).
Ayrıca IOException
dış işlevi de tedavi etmeniz gerekir .
Başka bir yol şudur:
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;
}
Bunun gereksiz bir kopyalaması yoktur.
FileTooBigException
özel bir uygulama istisnasıdır. MAX_FILE_SIZE
Sabiti bir uygulama parametreleri olduğunu.
Büyük dosyalar için muhtemelen bir akış işleme algoritması düşünmeli veya bellek eşleme kullanmalısınız (bkz. java.nio
).
Birinin söylediği gibi, Apache Commons File Utils aradığınızı alabilir
public static byte[] readFileToByteArray(File file) throws IOException
Örnek kullanım ( 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);
...
}
}
Bunu yapmak için NIO API'sini de kullanabilirsiniz. Toplam dosya boyutu (bayt cinsinden) bir int sığacak sürece bu kodla bunu yapabilirdi.
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 kullanarak beri onun çok hızlı düşünüyorum.
Java 8'iniz yoksa ve bana birkaç satır kod yazmaktan kaçınmak için büyük bir kütüphane eklemenin kötü bir fikir olduğunu kabul ediyorsanız:
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();
}
Akışı kapatmak için Arayan sorumludur.
// 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;
}
throw new IOException("File is too large!");
dosya çok büyük olduğunda ne yapmalıyız? Bununla ilgili herhangi bir örnek var mı?
Bunu yapmanın basit yolu:
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);
Dosyadan bayt okumanın en kolay yolu
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);
}
}
}
.*
, kötü uygulama olarak kabul edilir.
Guava'da size sunmak için Files.toByteArray () vardır . Birkaç avantajı vardır:
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);
Topluluk wiki yanıtıyla aynı yaklaşımı kullanarak, ancak daha temiz ve kutudan derleme (Apache Commons kütüphanelerini, örneğin Android'de içe aktarmak istemiyorsanız tercih edilen yaklaşım):
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();
}
Bunun en kolay yol olduğuna inanıyorum:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Geçerli dosya işaretçisinden başlayarak bu dosyadan b.length baytlarını bayt dizisine okur. Bu yöntem, istenen bayt sayısı okunana kadar dosyadan tekrar tekrar okur. Bu yöntem, istenen bayt sayısı okunana kadar, akışın sonu algılanıncaya veya bir istisna atılana kadar engellenir.
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Baytları önceden ayrılmış bir bayt arabelleğine okumak istiyorsanız, bu cevap yardımcı olabilir.
İlk tahmininiz muhtemelen InputStream read(byte[])
. Bununla birlikte, bu yöntemin kullanımı mantıksız bir şekilde zorlaştıran bir kusuru vardır: EOF ile karşılaşılmasa bile dizinin tamamen doldurulacağına dair bir garanti yoktur.
Bunun yerine bir göz atın DataInputStream readFully(byte[])
. Bu, giriş akışları için bir sarıcıdır ve yukarıda belirtilen sorunu içermez. Ayrıca, bu yöntem EOF ile karşılaşıldığında atar. Çok daha hoş.
Aşağıdaki yol sadece bir java.io.File dosyasını bir bayta [] dönüştürmekle kalmaz, aynı zamanda birçok farklı Java dosyası okuma yöntemini test ederken bir dosyada okumanın en hızlı yolu olduğunu buldum birbirine karşı :
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);
}
}
}
Üçüncü taraf kitaplıkları kullanmadan başka bir çözüm ekleyeyim. Scott ( link ) tarafından önerilen bir istisna işleme modelini yeniden kullanır . Ve çirkin bölümünü ayrı bir mesaja taşıdım (bazı FileUtils sınıflarında saklıyorum;))
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;
}
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);
}
}
}
Dosyadan bayt okumanın başka bir yolu
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();
}
}
//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"
Bunu dene :
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);
}
In JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();