উত্তর:
আপনি এটি এবং অনুরূপ কাজগুলি পরিচালনা করতে অ্যাপাচি কমন্স আইও ব্যবহার করতে পারেন ।
IOUtils
টাইপ একটি পড়তে একটি স্ট্যাটিক পন্থা নেই InputStream
এবং একটি ফিরতি byte[]
।
InputStream is;
byte[] bytes = IOUtils.toByteArray(is);
অভ্যন্তরীণভাবে এটি একটি তৈরি করে ByteArrayOutputStream
এবং আউটপুটে বাইটগুলি অনুলিপি করে, তারপরে কল করে toByteArray()
। এটি 4KiB- এর ব্লকগুলিতে বাইটগুলি অনুলিপি করে বড় ফাইলগুলি পরিচালনা করে।
FastArrayList
বা তাদের নরম ও দুর্বল রেফারেন্স মানচিত্রগুলি দেখুন এবং এই লাইব্রেরিটি কতটা "ভাল-পরীক্ষিত" তা আমাকে ফিরে আসতে বলুন। এটা তোলে আবর্জনা একটি গাদা এর
InputStream is;
byte[] filedata=ByteStreams.toByteArray(is);
আপনার নিজের থেকে প্রতিটি বাইট পড়তে হবে InputStream
এবং এটিতে এটি লিখতে হবে ByteArrayOutputStream
।
তারপরে আপনি কল করে অন্তর্নিহিত বাইট অ্যারে পুনরুদ্ধার করতে পারেন toByteArray()
:
InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
অবশেষে, বিশ বছর পরে, তৃতীয় পক্ষের লাইব্রেরির প্রয়োজন ছাড়াই একটি সহজ সমাধান রয়েছে, জাভা 9 এর জন্য ধন্যবাদ :
InputStream is;
…
byte[] array = is.readAllBytes();
সুবিধাগুলি readNBytes(byte[] b, int off, int len)
এবং transferTo(OutputStream)
পুনরাবৃত্তির প্রয়োজনগুলির সমাধানের জন্যও নোট করুন ।
ভ্যানিলা জাভা DataInputStream
এবং এর readFully
পদ্ধতিটি ব্যবহার করুন (কমপক্ষে জাভা 1.4 সাল থেকে বিদ্যমান):
...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...
এই পদ্ধতির আরও কিছু স্বাদ রয়েছে তবে আমি এই ব্যবহারের ক্ষেত্রে এটি সর্বদা ব্যবহার করি।
DataInputStream
প্রাথমিক স্ট্রিম থেকে প্রাথমিক ধরণের (লংস, শর্টস, চরস ...) পড়তে প্রাথমিকভাবে ব্যবহৃত হয়, তাই আমরা এই ব্যবহারটিকে শ্রেণীর অপব্যবহার হিসাবে দেখতে পারি।
InputStream.read
।
যদি আপনি গুগল পেয়ারা ব্যবহার করতে চান তবে এটি এতটা সহজ হবে:
byte[] bytes = ByteStreams.toByteArray(inputStream);
ByteStreams
সঙ্গে সটীক হয়@Beta
সর্বদা হিসাবে, এছাড়াও স্প্রিং ফ্রেমওয়ার্ক (3.2.2 থেকে বসন্ত-কোর) আপনার জন্য কিছু রয়েছে:StreamUtils.copyToByteArray()
public static byte[] getBytesFromInputStream(InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[0xFFFF];
for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
os.write(buffer, 0, len);
}
return os.toByteArray();
}
নিরাপদ সমাধান (close
প্রবাহেরদক্ষতার সাথেসঠিকভাবে):
জাভা 9+ সংস্করণ:
final byte[] bytes;
try (inputStream) {
bytes = inputStream.readAllBytes();
}
জাভা 8 সংস্করণ:
public static byte[] readAllBytes(InputStream inputStream) throws IOException {
final int bufLen = 4 * 0x400; // 4KB
byte[] buf = new byte[bufLen];
int readLen;
IOException exception = null;
try {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
outputStream.write(buf, 0, readLen);
return outputStream.toByteArray();
}
} catch (IOException e) {
exception = e;
throw e;
} finally {
if (exception == null) inputStream.close();
else try {
inputStream.close();
} catch (IOException e) {
exception.addSuppressed(e);
}
}
}
কোটলিন সংস্করণ (যখন জাভা 9+ অ্যাক্সেসযোগ্য নয়):
@Throws(IOException::class)
fun InputStream.readAllBytes(): ByteArray {
val bufLen = 4 * 0x400 // 4KB
val buf = ByteArray(bufLen)
var readLen: Int = 0
ByteArrayOutputStream().use { o ->
this.use { i ->
while (i.read(buf, 0, bufLen).also { readLen = it } != -1)
o.write(buf, 0, readLen)
}
return o.toByteArray()
}
}
নেস্টেড এড়ানোর use
জন্য এখানে দেখুন ।
আপনার কি সত্যই চিত্রটির প্রয়োজন byte[]
? আপনি ঠিক কীটি আশা করতে পারেন byte[]
- কোনও চিত্র ফাইলের সম্পূর্ণ সামগ্রী, ইমেজ ফাইলটি যে কোনও ফর্ম্যাটে এনকোডযুক্ত রয়েছে, বা আরজিবি পিক্সেল মান?
এখানে অন্যান্য উত্তরগুলি আপনাকে কীভাবে একটিতে ফাইল পড়তে হবে তা দেখায় byte[]
। আপনার byte[]
ফাইলটির সঠিক বিষয়বস্তু থাকবে এবং আপনাকে চিত্রের ডেটা দিয়ে কিছু করতে ডিকোড করতে হবে।
চিত্রগুলি পড়ার (এবং লেখার) জন্য জাভার স্ট্যান্ডার্ড এপিআই হ'ল ইমেজআইও এপিআই, যা আপনি প্যাকেজে খুঁজে পেতে পারেন javax.imageio
। আপনি কেবলমাত্র একটি একক লাইন কোডের একটি ফাইল থেকে একটি ছবিতে পড়তে পারেন:
BufferedImage image = ImageIO.read(new File("image.jpg"));
এটি আপনাকে একটি দেবে BufferedImage
, একটি নয় byte[]
। ইমেজ তথ্য এ পেতে, আপনি কল করতে পারেন getRaster()
উপর BufferedImage
। এটি আপনাকে একটি Raster
অবজেক্ট দেবে, যার পিক্সেল ডেটা অ্যাক্সেস করার পদ্ধতি রয়েছে (এতে বেশ কয়েকটি getPixel()
/getPixels()
পদ্ধতি রয়েছে)।
এপিআই ডকুমেন্টেশন লুকআপ জন্য javax.imageio.ImageIO
, java.awt.image.BufferedImage
, java.awt.image.Raster
ইত্যাদি
ইমেজআইও ডিফল্টরূপে বেশ কয়েকটি চিত্রের ফর্ম্যাটকে সমর্থন করে: জেপিইজি, পিএনজি, বিএমপি, ডাব্লুবিএমপি এবং জিআইএফ। আরও ফর্ম্যাটগুলির জন্য সমর্থন যুক্ত করা সম্ভব (আপনার একটি প্লাগ-ইন দরকার যা চিত্রের পরিষেবা পরিষেবা সরবরাহকারী ইন্টারফেসটি প্রয়োগ করে)।
নিম্নলিখিত টিউটোরিয়ালটি দেখুন: চিত্রগুলির সাথে কাজ করা
সেক্ষেত্রে কেউ এখনও নির্ভরতা ছাড়াই সমাধান খুঁজছেন এবং যদি আপনার কাছে ফাইল থাকে ।
1) ডেটা ইনপুট স্ট্রিম
byte[] data = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(data);
dis.close();
2) বাইটআর্যআউটপুট স্ট্রিম
InputStream is = new FileInputStream(file);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[(int) file.length()];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
3) র্যান্ডমএকসেসফাইল
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte[] data = new byte[(int) raf.length()];
raf.readFully(data);
আপনি যদি অ্যাপাচি কমন্স-আইও লাইব্রেরিটি ব্যবহার করতে না চান তবে এই স্নিপেটটি sun.misc.IOUtils ক্লাস থেকে নেওয়া হয়েছে। এটি বাইটবফার্স ব্যবহার করে সাধারণ প্রয়োগের চেয়ে প্রায় দ্বিগুণ দ্রুত:
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
byte[] output = {};
if (length == -1) length = Integer.MAX_VALUE;
int pos = 0;
while (pos < length) {
int bytesToRead;
if (pos >= output.length) { // Only expand when there's no room
bytesToRead = Math.min(length - pos, output.length + 1024);
if (output.length < pos + bytesToRead) {
output = Arrays.copyOf(output, pos + bytesToRead);
}
} else {
bytesToRead = output.length - pos;
}
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) {
if (readAll && length != Integer.MAX_VALUE) {
throw new EOFException("Detect premature EOF");
} else {
if (output.length != pos) {
output = Arrays.copyOf(output, pos);
}
break;
}
}
pos += cc;
}
return output;
}
@ অ্যাডামস্কি: আপনি পুরোপুরি বাফার এড়াতে পারবেন।
Http://www.exampledepot.com/egs/java.io/File2ByteArray.html থেকে কোড অনুলিপি করা হয়েছে (হ্যাঁ, এটি খুব ভার্জোজ, তবে অন্যান্য সমাধানের মতো মেমরির অর্ধেক আকার প্রয়োজন))
// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// 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
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
is.close()
যদি offset < bytes.length
বা InputStream
যদি সেই ব্যতিক্রম নিক্ষিপ্ত তা বন্ধ করা হবে না।
Input Stream is ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
bos.write(next);
next = in.read();
}
bos.flush();
byte[] result = bos.toByteArray();
bos.close();
InputStream
একটি BufferedInputStream
যে কোড সামনে ওএস-কল কমানো ও উল্লেখযোগ্যভাবে কর্মক্ষমতা অপূর্ণতা প্রশমিত হবে, যে কোড এখনও অন্য এক বাফার থেকে অপ্রয়োজনীয় ম্যানুয়াল অনুলিপি কাজ করতে হবে।
জাভা 9 আপনাকে শেষ পর্যন্ত একটি দুর্দান্ত পদ্ধতি দেবে:
InputStream in = ...;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo( bos );
byte[] bytes = bos.toByteArray();
InputStram.readAllBytes()
ওয়ান লাইনার মধ্যে পার্থক্য কী ?
আমি জানি এটি অনেক দেরি হয়ে গেছে তবে এখানে আমি মনে করি এটি পরিষ্কার সমাধান যা আরও পঠনযোগ্য ...
/**
* method converts {@link InputStream} Object into byte[] array.
*
* @param stream the {@link InputStream} Object.
* @return the byte[] array representation of received {@link InputStream} Object.
* @throws IOException if an error occurs.
*/
public static byte[] streamToByteArray(InputStream stream) throws IOException {
byte[] buffer = new byte[1024];
ByteArrayOutputStream os = new ByteArrayOutputStream();
int line = 0;
// read bytes from stream, and store them in buffer
while ((line = stream.read(buffer)) != -1) {
// Writes bytes from byte array (buffer) into output stream.
os.write(buffer, 0, line);
}
stream.close();
os.flush();
os.close();
return os.toByteArray();
}
জাভা 8 ওয়ে ( বাফার্ডারিডার এবং অ্যাডাম বিয়েনকে ধন্যবাদ )
private static byte[] readFully(InputStream input) throws IOException {
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) {
return buffer.lines().collect(Collectors.joining("\n")).getBytes(<charset_can_be_specified>);
}
}
নোট করুন যে এই দ্রবণটি ক্যারিজ রিটার্ন ('\ r') মুছবে এবং অনুপযুক্ত হতে পারে।
String
। ওপি চাইছে byte[]
।
\r
সমস্যা হতে পারে না । এই পদ্ধতিটি বাইটগুলিকে অক্ষরগুলিতে রূপান্তর করে এবং আবার ফিরে আসে (ইনপুটস্ট্র্রিমার্ডারের জন্য ডিফল্ট অক্ষর সেট ব্যবহার করে)। ডিফল্ট অক্ষর এনকোডিংয়ে বৈধ নয় এমন কোনও বাইট (লিনাক্সে ইউটিএফ -8 এর জন্য -1 বলুন) দূষিত হবে, সম্ভবত বাইটের সংখ্যাও পরিবর্তন করবে।
আমি জঞ্জাল ডেটা লেখার জন্য একটি ফিক্স সহ @ নুমানের উত্তর সম্পাদনা করার চেষ্টা করেছি তবে সম্পাদনা প্রত্যাখ্যান করা হয়েছিল। কোডের এই সংক্ষিপ্ত অংশটি উজ্জ্বল কিছু না হলেও আমি এর চেয়ে ভাল আর কোনও উত্তর দেখতে পাচ্ছি না। এখানে আমার কাছে সবচেয়ে বেশি অর্থবোধ রয়েছে:
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; // you can configure the buffer size
int length;
while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length); //copy streams
in.close(); // call this in a finally block
byte[] result = out.toByteArray();
বিটিডব্লিউ বাইটআরআউটপুট স্ট্রিম বন্ধ করার দরকার নেই। চেষ্টা / শেষ পর্যন্ত পাঠযোগ্যতার জন্য বাদ দেওয়া নির্মাণগুলি
InputStream.available()
ডকুমেন্টেশন দেখুন :
এটি উপলব্ধি করা বিশেষভাবে গুরুত্বপূর্ণ যে আপনার কোনও ধারক আকারের জন্য এই পদ্ধতিটি ব্যবহার করা উচিত নয় এবং ধারনা করা হয় যে আপনি ধারকটির আকার পরিবর্তন করার প্রয়োজন ছাড়াই প্রবাহের পুরোতাটি পড়তে পারেন। এই জাতীয় কলকারীদের সম্ভবত তারা বাইটআরআর আউটপুট স্ট্রিমে পড়া সমস্ত কিছু লিখতে হবে এবং এটিকে একটি বাইট অ্যারেতে রূপান্তর করতে হবে। বিকল্পভাবে, আপনি যদি কোনও ফাইল থেকে পড়ছেন তবে ফাইল. দৈর্ঘ্য ফাইলের বর্তমান দৈর্ঘ্য ফেরত দেয় (যদিও ধরে নিলে ফাইলের দৈর্ঘ্য পরিবর্তন হতে পারে না ভুল হতে পারে, একটি ফাইল পড়া সহজাতভাবে বৈষম্য)।
কোনও কারণে এটি টেবিলের বাইরে থাকলে কোনও ডেটা ইনপুট স্ট্রিমে এটিকে আবদ্ধ করুন, এটি কোনও হাতুড়ি পঠন করতে ব্যবহার করুন যতক্ষণ না এটি আপনাকে একটি -1 দেয় বা আপনি যে ব্লকটি জিজ্ঞাসা করেছিলেন সম্পূর্ণ না দেয়।
public int readFully(InputStream in, byte[] data) throws IOException {
int offset = 0;
int bytesRead;
boolean read = false;
while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
read = true;
offset += bytesRead;
if (offset >= data.length) {
break;
}
}
return (read) ? offset : -1;
}
এস 3 অবজেক্টকে বাইটআরেতে রূপান্তর করার সময় আমরা কয়েকটি AWS লেনদেনের জন্য কিছুটা বিলম্ব দেখছি।
দ্রষ্টব্য: এস 3 অবজেক্টটি পিডিএফ ডকুমেন্ট (সর্বোচ্চ আকার 3 এমবি)।
S3 অবজেক্টটিকে বাইটআররে রূপান্তর করতে আমরা # 1 বিকল্পটি ব্যবহার করছি (org.apache.commons.io.IOUtils)। আমরা লক্ষ করেছি যে এস 3 এস -3 অবজেক্টকে বাইটআররে রূপান্তর করার জন্য ইনবিল্ড আইইউটিস পদ্ধতি সরবরাহ করে, দেরি এড়াতে S3 অবজেক্টটি বাইটআররে রূপান্তর করার সর্বোত্তম উপায় কোনটি তা নিশ্চিত করার জন্য আমরা আপনাকে অনুরোধ করছি।
বিকল্প 1:
import org.apache.commons.io.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);
বিকল্প # 2:
import com.amazonaws.util.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);
এছাড়াও আমাদের কাছে s3 অবজেক্টকে বাইটায়ারে রূপান্তর করার আরও ভাল উপায় আছে কিনা তা আমাকে জানান let
অন্য ক্ষেত্রে স্ট্রিমের মাধ্যমে সঠিক বাইট অ্যারে পেতে সার্ভারে অনুরোধ প্রেরণের পরে এবং প্রতিক্রিয়ার জন্য অপেক্ষা করছে waiting
/**
* Begin setup TCP connection to PC app
* to open integrate connection between mobile app and pc app (or mobile app)
*/
mSocket = new Socket(IP, port);
// mSocket.setSoTimeout(30000);
DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream());
String str = "MobileRequest#" + params[0] + "#<EOF>";
mDos.write(str.getBytes());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/* Since data are accepted as byte, all of them will be collected in the
following byte array which initialised with accepted data length. */
DataInputStream mDis = new DataInputStream(mSocket.getInputStream());
byte[] data = new byte[mDis.available()];
// Collecting data into byte array
for (int i = 0; i < data.length; i++)
data[i] = mDis.readByte();
// Converting collected data in byte array into String.
String RESPONSE = new String(data);
আপনি যদি বাইটআর্যআউটপুট স্ট্রিম ব্যবহার করেন তবে আপনি একটি অতিরিক্ত অনুলিপি করছেন। আপনি যদি স্ট্রিমটি পড়া শুরু করার আগে দৈর্ঘ্য জানেন তবে (উদাহরণস্বরূপ ইনপুট স্ট্রিম আসলে একটি ফাইললাইনপ্রেস্টম, এবং আপনি ফাইলটিতে ফাইল.লেন্থ () কল করতে পারেন, বা ইনপুটস্ট্রিমটি জিপফাইলে প্রবেশকারী ইনপুটস্ট্রিম, এবং আপনি জিপইন্ট্রি কল করতে পারেন। দৈর্ঘ্য ()), তারপরে এটি সরাসরি বাইট [] অ্যারেতে লিখতে অনেক বেশি ভাল - এটি অর্ধেক স্মৃতি ব্যবহার করে এবং সময় সাশ্রয় করে।
// Read the file contents into a byte[] array
byte[] buf = new byte[inputStreamLength];
int bytesRead = Math.max(0, inputStream.read(buf));
// If needed: for safety, truncate the array if the file may somehow get
// truncated during the read operation
byte[] contents = bytesRead == inputStreamLength ? buf
: Arrays.copyOf(buf, bytesRead);
স্ট্রিমটি পড়ার সময় উপরের শেষ লাইনটি এনবি ফাইলগুলি কেটে ফেলা নিয়ে ডিল করে, আপনার যদি সেই সম্ভাবনাটি পরিচালনা করতে হয় তবে ফাইলটি যদি প্রবাহটি পড়ার সময় আরও বেশি হয়ে যায়, তবে বাইট [] অ্যারেতে থাকা সামগ্রীগুলি দীর্ঘায়িত করা হবে না নতুন ফাইলের বিষয়বস্তু অন্তর্ভুক্ত করতে অ্যারেটি কেবল পুরানো দৈর্ঘ্যের ইনপুটস্ট্রিমলাইনে ছাঁটা হবে ।
আমি এটি ব্যবহার করি
public static byte[] toByteArray(InputStream is) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
byte[] b = new byte[4096];
int n = 0;
while ((n = is.read(b)) != -1) {
output.write(b, 0, n);
}
return output.toByteArray();
} finally {
output.close();
}
}
এটি আমার অনুলিপি-সংস্করণ:
@SuppressWarnings("empty-statement")
public static byte[] inputStreamToByte(InputStream is) throws IOException {
if (is == null) {
return null;
}
// Define a size if you have an idea of it.
ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
byte[] read = new byte[512]; // Your buffer size.
for (int i; -1 != (i = is.read(read)); r.write(read, 0, i));
is.close();
return r.toByteArray();
}
জাভা 7 এবং তারপরে:
import sun.misc.IOUtils;
...
InputStream in = ...;
byte[] buf = IOUtils.readFully(in, -1, false);
sun.misc.IOUtils
"জাভা 7" নয়। এটি একটি মালিকানাধীন, বাস্তবায়ন নির্দিষ্ট শ্রেণি যা অন্য জেআরই বাস্তবায়নে উপস্থিত নাও হতে পারে এবং পরের রিলিজগুলির কোনও সতর্কতা ছাড়াই অদৃশ্য হয়ে যায়।
এখানে একটি অনুকূলিত সংস্করণ, যা যতটা সম্ভব ডেটা বাইট অনুলিপি করা এড়াতে চেষ্টা করে:
private static byte[] loadStream (InputStream stream) throws IOException {
int available = stream.available();
int expectedSize = available > 0 ? available : -1;
return loadStream(stream, expectedSize);
}
private static byte[] loadStream (InputStream stream, int expectedSize) throws IOException {
int basicBufferSize = 0x4000;
int initialBufferSize = (expectedSize >= 0) ? expectedSize : basicBufferSize;
byte[] buf = new byte[initialBufferSize];
int pos = 0;
while (true) {
if (pos == buf.length) {
int readAhead = -1;
if (pos == expectedSize) {
readAhead = stream.read(); // test whether EOF is at expectedSize
if (readAhead == -1) {
return buf;
}
}
int newBufferSize = Math.max(2 * buf.length, basicBufferSize);
buf = Arrays.copyOf(buf, newBufferSize);
if (readAhead != -1) {
buf[pos++] = (byte)readAhead;
}
}
int len = stream.read(buf, pos, buf.length - pos);
if (len < 0) {
return Arrays.copyOf(buf, pos);
}
pos += len;
}
}
কোটলিনে সমাধান (অবশ্যই জাভাতেও কাজ করবে), আপনি যখন আকারটি জানেন বা না জানেন তখন উভয়েরই অন্তর্ভুক্ত রয়েছে:
fun InputStream.readBytesWithSize(size: Long): ByteArray? {
return when {
size < 0L -> this.readBytes()
size == 0L -> ByteArray(0)
size > Int.MAX_VALUE -> null
else -> {
val sizeInt = size.toInt()
val result = ByteArray(sizeInt)
readBytesIntoByteArray(result, sizeInt)
result
}
}
}
fun InputStream.readBytesIntoByteArray(byteArray: ByteArray,bytesToRead:Int=byteArray.size) {
var offset = 0
while (true) {
val read = this.read(byteArray, offset, bytesToRead - offset)
if (read == -1)
break
offset += read
if (offset >= bytesToRead)
break
}
}
আপনি যদি আকারটি জানেন তবে এটি অন্যান্য সমাধানের তুলনায় দ্বিগুণ মেমরি ব্যবহার করা বাঁচায় (একটি সংক্ষিপ্ত মুহূর্তে, তবে এটি কার্যকর হতে পারে)। এর কারণ আপনাকে পুরো স্ট্রিমটি শেষ পর্যন্ত পড়তে হবে এবং তারপরে এটিকে একটি বাইট অ্যারেতে রূপান্তর করতে হবে (অ্যারেলিস্টের সমান যা আপনি কেবল একটি অ্যারেতে রূপান্তর করেন)।
সুতরাং, উদাহরণস্বরূপ, আপনি যদি অ্যান্ড্রয়েডে থাকেন এবং আপনি হ্যান্ডেল করার জন্য কিছুটা উরি পেয়েছেন তবে আপনি এটি ব্যবহার করে আকারটি পাওয়ার চেষ্টা করতে পারেন:
fun getStreamLengthFromUri(context: Context, uri: Uri): Long {
context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.SIZE), null, null, null)?.use {
if (!it.moveToNext())
return@use
val fileSize = it.getLong(it.getColumnIndex(MediaStore.MediaColumns.SIZE))
if (fileSize > 0)
return fileSize
}
//if you wish, you can also get the file-path from the uri here, and then try to get its size, using this: https://stackoverflow.com/a/61835665/878126
FileUtilEx.getFilePathFromUri(context, uri, false)?.use {
val file = it.file
val fileSize = file.length()
if (fileSize > 0)
return fileSize
}
context.contentResolver.openInputStream(uri)?.use { inputStream ->
if (inputStream is FileInputStream)
return inputStream.channel.size()
else {
var bytesCount = 0L
while (true) {
val available = inputStream.available()
if (available == 0)
break
val skip = inputStream.skip(available.toLong())
if (skip < 0)
break
bytesCount += skip
}
if (bytesCount > 0L)
return bytesCount
}
}
return -1L
}
/*InputStream class_InputStream = null;
I am reading class from DB
class_InputStream = rs.getBinaryStream(1);
Your Input stream could be from any source
*/
int thisLine;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((thisLine = class_InputStream.read()) != -1) {
bos.write(thisLine);
}
bos.flush();
byte [] yourBytes = bos.toByteArray();
/*Don't forget in the finally block to close ByteArrayOutputStream & InputStream
In my case the IS is from resultset so just closing the rs will do it*/
if (bos != null){
bos.close();
}