සමස්තයක්ම InputStream
බයිට් අරාවකට කියවන්නේ කෙසේද ?
Answers:
මේ හා සමාන කාර්යයන් හැසිරවීමට ඔබට Apache Commons IO භාවිතා කළ හැකිය .
මෙම IOUtils
වර්ගය සඳහා කියවීමට ස්ථිතික ක්රමය ඇති InputStream
අතර නැවත byte[]
.
InputStream is;
byte[] bytes = IOUtils.toByteArray(is);
අභ්යන්තරව මෙය a නිර්මාණය කර ByteArrayOutputStream
බයිට් ප්රතිදානයට පිටපත් කර ඇමතුම් ලබා ගනී toByteArray()
. එය 4KiB බ්ලොක් වල බයිට් පිටපත් කිරීමෙන් විශාල ගොනු හසුරුවයි.
FastArrayList
හෝ ඒවායේ මෘදු හා දුර්වල යොමු සිතියම් දෙස බලා මෙම පුස්තකාලය කෙතරම් “හොඳින් පරීක්ෂා කර ඇත්දැයි” මට කියන්න. එය කුණු
InputStream is;
byte[] filedata=ByteStreams.toByteArray(is);
ඔබ ඔබේ එක් එක් බයිටය කියවා InputStream
එය a ට ලිවිය යුතුය 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
සඳහා මෙහි බලන්න .
පරිමාණ අනුවාදය (ජාවා 9+ ප්රවේශ කළ නොහැකි විට):
def readAllBytes(inputStream: InputStream): Array[Byte] =
Stream.continually(inputStream.read).takeWhile(_ != -1).map(_.toByte).toArray
ඔබට ඇත්ත වශයෙන්ම රූපය byte[]
අවශ්යද? byte[]
රූප ගොනුවක සම්පූර්ණ අන්තර්ගතය, රූප ගොනුවේ ඇති ඕනෑම ආකෘතියකින් කේතනය කර ඇති හෝ RGB පික්සල් අගයන්ගෙන් ඔබ හරියටම අපේක්ෂා කරන්නේ කුමක්ද?
මෙහි ඇති වෙනත් පිළිතුරු මඟින් ගොනුවක් කියවිය යුතු ආකාරය පෙන්වයි byte[]
. ඔබගේ byte[]
ගොනුවේ නිශ්චිත අන්තර්ගතයන් අඩංගු වන අතර රූප දත්ත සමඟ ඕනෑම දෙයක් කිරීමට ඔබට එය විකේතනය කළ යුතුය.
පින්තූර කියවීම (සහ ලිවීම) සඳහා ජාවාහි සම්මත API යනු ImageIO API වන අතර එය ඔබට පැකේජයෙන් සොයාගත හැකිය javax.imageio
. තනි කේත පේළියක් සහිත ගොනුවකින් ඔබට රූපයකින් කියවිය හැකිය:
BufferedImage image = ImageIO.read(new File("image.jpg"));
මෙය ඔබට ලබා දෙනු ඇත BufferedImage
, අ byte[]
. මෙම රූප දත්ත දී ලබා ගැනීමට, ඔබ ඇමතිය හැකි getRaster()
මත BufferedImage
. මෙහි අරුත වන්නේ, ඔබ විසින් ලබා දෙනු ඇත Raster
යන පික්සල දත්ත වෙත ප්රවේශ වීමට (එය කිහිපයක් තිබේ ක්රම ඇති වස්තුව, getPixel()
/ getPixels()
ක්රම).
සඳහා API ප්රලේඛනය විමසුම් javax.imageio.ImageIO
, java.awt.image.BufferedImage
, java.awt.image.Raster
ආදිය
ImageIO පෙරනිමියෙන් රූප ආකෘති ගණනාවකට සහය දක්වයි: JPEG, PNG, BMP, WBMP සහ GIF. තවත් ආකෘති සඳහා සහය එක් කළ හැකිය (ඔබට ImageIO සේවා සැපයුම්කරු අතුරුමුහුණත ක්රියාත්මක කරන ප්ලග් ඉන් එකක් අවශ්ය වේ).
පහත නිබන්ධනයද බලන්න: රූප සමඟ වැඩ කිරීම
යමෙකු තවමත් යැපීමකින් තොරව විසඳුමක් සොයමින් සිටින අතර ඔබට ගොනුවක් තිබේ නම් .
1) DataInputStream
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
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte[] data = new byte[(int) raf.length()];
raf.readFully(data);
ඔබට Apache commons-io පුස්තකාලය භාවිතා කිරීමට අවශ්ය නැතිනම්, මෙම ස්නිපටය ගනු ලබන්නේ 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;
}
D ඇඩම්ස්කි: ඔබට බෆරය සම්පූර්ණයෙන්ම වළක්වා ගත හැකිය.
කේතය 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>);
}
}
සටහන මෙම විසඳුම දමනවා බව carriage return ( '\ r') සහ නුසුදුසු විය හැක.
String
. OP ඉල්ලයි byte[]
.
\r
ගැටලුවක් විය හැකි පමණක් නොවේ. මෙම ක්රමය මඟින් බයිට් අක්ෂර බවට පරිවර්තනය කර නැවත නැවතත් (InputStreamReader සඳහා පෙරනිමි අක්ෂර කට්ටලය භාවිතා කරමින්). පෙරනිමි අක්ෂර කේතීකරණයේ වලංගු නොවන ඕනෑම බයිට් (ලිනක්ස් හි UTF-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();
btw ByteArrayOutputStream වසා දැමිය යුතු නැත. කියවීමේ හැකියාව සඳහා අතහැර දමා ඇති උත්සාහයන් / අවසානයේ ඉදිකිරීම්
InputStream.available()
ප්රලේඛනය බලන්න :
කන්ටේනරයක ප්රමාණයට ඔබ මෙම ක්රමය භාවිතා නොකළ යුතු බව වටහා ගැනීම විශේෂයෙන් වැදගත් වන අතර කන්ටේනරයේ ප්රමාණය වෙනස් කිරීමකින් තොරව ඔබට මුළු ධාරාවම කියවිය හැකි යැයි උපකල්පනය කරන්න. එවැනි අමතන්නන් බොහෝ විට තමන් කියවන සෑම දෙයක්ම බයිට්ආරේ ඕට්පුට්ස්ට්රීම් වෙත ලියා එය බයිට් අරාවකට පරිවර්තනය කළ යුතුය. විකල්පයක් ලෙස, ඔබ ගොනුවකින් කියවන්නේ නම්, File.length ගොනුවේ වත්මන් දිග නැවත ලබා දෙයි (ගොනුවේ දිග වෙනස් කළ නොහැකි යැයි උපකල්පනය කළත් වැරදියි, ගොනුවක් කියවීම සහජයෙන්ම විචක්ෂණශීලී වේ).
කිසියම් හේතුවක් නිසා එය මේසයෙන් ඉවතට ඇත්නම් එය ඩේටා ඉන්පුට්ස්ට්රීම් එකක ඔතා තබන්න, එය ඔබට -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;
}
S3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කරන අතරම AWS ගනුදෙනු කිහිපයක් සඳහා යම් ප්රමාදයක් අපට පෙනේ.
සටහන: S3 වස්තුව PDF ලේඛනයකි (උපරිම ප්රමාණය 3 mb).
S3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කිරීම සඳහා අපි # 1 (org.apache.commons.io.IOUtils) විකල්පය භාවිතා කරමු. එස් 3 වස්තුව බයිට්ආරේ බවට පරිවර්තනය කිරීම සඳහා එස් 3 ඉන්බිල්ඩ් අයිඕටිල්ස් ක්රමය සපයන බව අපි දැක ඇත්තෙමු, ප්රමාදය වළක්වා ගැනීම සඳහා එස් 3 වස්තුව බයිට්ආරේ වෙත පරිවර්තනය කිරීමට හොඳම ක්රමය කුමක්දැයි තහවුරු කරන ලෙස අපි ඔබෙන් ඉල්ලා සිටිමු.
විකල්ප 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 වස්තුව බයිටරේ බවට පරිවර්තනය කිරීමට අපට වෙනත් හොඳ ක්රමයක් තිබේදැයි මට දන්වන්න
අනෙක් නඩුව ප්රවාහය හරහා නිවැරදි බයිට් අරාව ලබා ගැනීම, සේවාදායකයට ඉල්ලීමක් යැවීමෙන් පසුව සහ ප්රතිචාරය බලාපොරොත්තුවෙන්.
/**
* 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);
ඔබ ByteArrayOutputStream භාවිතා කරන්නේ නම් ඔබ අමතර පිටපතක් කරයි. ඔබ එය කියවීමට පෙර ධාරාවේ දිග දන්නේ නම් (උදා: InputStream ඇත්ත වශයෙන්ම FileInputStream වන අතර, ඔබට ගොනුවේ file.length () අමතන්න, නැතහොත් InputStream යනු zipfile ඇතුළත් කිරීමක් InputStream වන අතර ඔබට zipEntry අමතන්න. දිග ()), එවිට කෙලින්ම බයිට් [] අරාව තුළට ලිවීම වඩා හොඳය - එය මතකයෙන් අඩක් භාවිතා කරන අතර කාලය ඉතිරි කරයි.
// 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” නොවේ. එය හිමිකාරීත්ව, ක්රියාත්මක කිරීමේ විශේෂිත පංතියක් වන අතර එය වෙනත් JRE ක්රියාත්මක කිරීම් වල නොපවතින අතර ඊළඟ නිකුතුවක කිසිදු අනතුරු ඇඟවීමකින් තොරව අතුරුදහන් විය හැකිය.
මෙන්න හැකි තරම් දත්ත බයිට් පිටපත් කිරීමෙන් වැළකී සිටීමට උත්සාහ කරන ප්රශස්තිකරණය කළ අනුවාදයකි:
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
}
නැවත භාවිතා කළ හැකි වස්තු-නැඹුරු ජාවා සංරචක සමඟ ඔබට පතොක් පුස්තකාලය භාවිතා කළ හැකිය . OOP මෙම පුස්තකාලය මගින් අවධාරණය කරනු ලැබේ, එබැවින් ස්ථිතික ක්රම, NULL සහ යනාදිය සැබෑ වස්තූන් සහ ඒවායේ ගිවිසුම් (අතුරුමුහුණත්) පමණි. InputStream කියවීම වැනි සරල මෙහෙයුමක් ඒ ආකාරයෙන් කළ හැකිය
final InputStream input = ...;
final Bytes bytes = new BytesOf(input);
final byte[] array = bytes.asBytes();
Assert.assertArrayEquals(
array,
new byte[]{65, 66, 67}
);
Bytes
දත්ත ව්යුහය සමඟ වැඩ කිරීම සඳහා විශේෂිත වර්ගයක් තිබීම, byte[]
අත ළඟ ඇති කාර්යයන් විසඳීම සඳහා OOP උපක්රම භාවිතා කිරීමට අපට හැකියාව ලබා දෙයි. කාර්ය පටිපාටික “උපයෝගීතා” ක්රමයක් අපට කිරීමට තහනම් කරයි. උදාහරණයක් ලෙස, ඔබ මෙයින් කියවා ඇති බයිට් 64 බේස් 64 වෙත යොමු කළ යුතුය InputStream
. මෙම අවස්ථාවේදී ඔබ සැරසිලි රටාව භාවිතා කරන අතර Base64 සඳහා ක්රියාත්මක කිරීමේදී බයිට් වස්තුව ඔතා.
පතොක් දැනටමත් එවැනි ක්රියාත්මක කිරීමක් සපයයි:
final Bytes encoded = new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
);
Assert.assertEquals(new TextOf(encoded).asString(), "WFla");
සැරසිලි රටාව භාවිතා කිරීමෙන් ඔබට ඒවා එකම ආකාරයකින් විකේතනය කළ හැකිය
final Bytes decoded = new Base64Bytes(
new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
)
);
Assert.assertEquals(new TextOf(decoded).asString(), "XYZ");
ඔබගේ කර්තව්යය කුමක් වුවත් Bytes
එය විසඳීම සඳහා ඔබටම ක්රියාත්මක කළ හැකිය .