Hello as you can see below I m trying to make a (android) app which check md5 hash of file
this code works only for small files
can someone help me?
final TextView informations = (TextView) findViewById(R.id.Informations);
final EditText input = (EditText) findViewById(R.id.ToCrack);
String filepath = data.getDataString();
String rawtext;
String hash;
StringBuilder text = new StringBuilder();
filepath = filepath.split("//")[1];
File file = new File(filepath);
Toast.makeText(getApplicationContext(),"Loading: "+filepath,Toast.LENGTH_LONG).show();
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
try{
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while (dis.available() != 0){
text.append(dis.readLine()+"\n");
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
try{
fis.close();
bis.close();
dis.close();
}
catch (IOException ex){
ex.printStackTrace();
}
}
rawtext = text.toString().substring(0, text.length()-1);
hash = new MD5(rawtext).hexdigest();
if (hash.equals(input.getText().toString())){
informations.setText("Hash correspond with the file!");
}
else{
informations.setText("File hash= "+hash+"\nHashes does not correspond :(");
}
Toast.makeText(getApplicationContext(),"Copied file hash to clipboard.",Toast.LENGTH_LONG).show();
Mobile device environments such as Android have limitations w.r.t the amount of memory that can be consumed by an application. Hence, reading large files to an in-memory data store as done in your code (using StringBuffer) is going to throw an OutOfMemory error.
Take a look at this question to know how you can overcome the problem.
Related
I am trying to transfer a .mp4 file using WebRTC and it's DataChannel. In order to do that I am breaking the file into chunks like below:
FileInputStream is = new FileInputStream(file);
byte[] chunk = new byte[260000];
int chunkLen = 0;
sentFileByte = new ArrayList<>();
while ((chunkLen = is.read(chunk)) != -1) {
sentFileByte.add(chunk);
}
After that, sending the chunks by index like:
byte[] b = sentFileByte.get(index);
ByteBuffer bb = ByteBuffer.wrap(b);
bb.put(b);
bb.flip();
dataChannel.send(new DataChannel.Buffer(bb, true));
On the receiver end I am receiving the chunks and adding it to an Arraylist
receivedFileByteArr.add(chunkByteArr);
After receiving all the chunks successfully I am trying to convert these in to a file like below:
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/" + fileName;
File file = new File(path);
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int i = 0; i < receivedFileByteArr.size(); i++) {
fileOutputStream.write(receivedFileByteArr.get(i));
}
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After completing all these steps, file is created successfully. File size is also same. But problem is the file is not playable in any video player. I guess I am making some mistake on FileInputStream and FileOutputStream. I need help to fix this error.
With Java:
I have a byte[] that represents a file.
How do I write this to a file (ie. C:\myfile.pdf)
I know it's done with InputStream, but I can't seem to work it out.
Use Apache Commons IO
FileUtils.writeByteArrayToFile(new File("pathname"), myByteArray)
Or, if you insist on making work for yourself...
try (FileOutputStream fos = new FileOutputStream("pathname")) {
fos.write(myByteArray);
//fos.close(); There is no more need for this line since you had created the instance of "fos" inside the try. And this will automatically close the OutputStream
}
Without any libraries:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(bytes);
}
With Google Guava:
Files.write(bytes, new File(path));
With Apache Commons:
FileUtils.writeByteArrayToFile(new File(path), bytes);
All of these strategies require that you catch an IOException at some point too.
Another solution using java.nio.file:
byte[] bytes = ...;
Path path = Paths.get("C:\\myfile.pdf");
Files.write(path, bytes);
Also since Java 7, one line with java.nio.file.Files:
Files.write(new File(filePath).toPath(), data);
Where data is your byte[] and filePath is a String. You can also add multiple file open options with the StandardOpenOptions class. Add throws or surround with try/catch.
From Java 7 onward you can use the try-with-resources statement to avoid leaking resources and make your code easier to read. More on that here.
To write your byteArray to a file you would do:
try (FileOutputStream fos = new FileOutputStream("fullPathToFile")) {
fos.write(byteArray);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Try an OutputStream or more specifically FileOutputStream
Basic example:
String fileName = "file.test";
BufferedOutputStream bs = null;
try {
FileOutputStream fs = new FileOutputStream(new File(fileName));
bs = new BufferedOutputStream(fs);
bs.write(byte_array);
bs.close();
bs = null;
} catch (Exception e) {
e.printStackTrace()
}
if (bs != null) try { bs.close(); } catch (Exception e) {}
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
////////////////////////// 1] File to Byte [] ///////////////////
Path path = Paths.get(p);
byte[] data = null;
try {
data = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(Agent1.class.getName()).log(Level.SEVERE, null, ex);
}
/////////////////////// 2] Byte [] to File ///////////////////////////
File f = new File(fileName);
byte[] fileContent = msg.getByteSequenceContent();
Path path = Paths.get(f.getAbsolutePath());
try {
Files.write(path, fileContent);
} catch (IOException ex) {
Logger.getLogger(Agent2.class.getName()).log(Level.SEVERE, null, ex);
}
I know it's done with InputStream
Actually, you'd be writing to a file output...
This is a program where we are reading and printing array of bytes offset and length using String Builder and Writing the array of bytes offset length to the new file.
`Enter code here
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//*This is a program where we are reading and printing array of bytes offset and length using StringBuilder and Writing the array of bytes offset length to the new file*//
public class ReadandWriteAByte {
public void readandWriteBytesToFile(){
File file = new File("count.char"); //(abcdefghijk)
File bfile = new File("bytefile.txt");//(New File)
byte[] b;
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream (file);
fos = new FileOutputStream (bfile);
b = new byte [1024];
int i;
StringBuilder sb = new StringBuilder();
while ((i = fis.read(b))!=-1){
sb.append(new String(b,5,5));
fos.write(b, 2, 5);
}
System.out.println(sb.toString());
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis != null);
fis.close(); //This helps to close the stream
}catch (IOException e){
e.printStackTrace();
}
}
}
public static void main (String args[]){
ReadandWriteAByte rb = new ReadandWriteAByte();
rb.readandWriteBytesToFile();
}
}
O/P in console : fghij
O/P in new file :cdefg
You can try Cactoos:
new LengthOf(new TeeInput(array, new File("a.txt"))).value();
More details: http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html
I'm new to android studio and I have this textview which shows the data that is stored to my text file. If I click the button, it should read the data inside the text file, add integer and the sum should replace the existing data in the text file. However when I return to the activity which show's the textView with the new data in the text file, it does not change.
Here's the code for my textView
txt_stars = (TextView) findViewById(R.id.txtStars);
try {
FileInputStream fileInputStream = openFileInput("Stars.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star=bufferedReader.readLine()) != null){
stringBuffer.append(star);
}
txt_stars.setText(stringBuffer.toString());
}
catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And the code for the button
Integer stars, totalStars;
public void onClick(DialogInterface dialog, int whichButton) {
try {
FileInputStream fileInputStream = openFileInput("Stars.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star = bufferedReader.readLine()) != null) {
stringBuffer.append(star);
}
stars = Integer.parseInt(stringBuffer.toString());
totalStars = stars + 50;
//is this acceptable?
FileOutputStream fileOutputStream = openFileOutput("Stars.txt", MODE_PRIVATE);
fileOutputStream.write(totalStars.toString().getBytes());
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Intent nextForm = new Intent(".MainActivity");
startActivity(nextForm);
}
And also, where can I find the created text file in my phone so that I can assure that the text file is created? I'm using Android studio 1.5.1 and running the app to my phone.
I have this in my manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Is there anything I should do to locate and create the text file?
I have been stuck here for days. Please help me.
Thanks a lot!
This might be due to a FileNotFoundException when you'd read the file in the save method. When you try to update the file and write into it, you don't separate the try/catch methods so you might have an exception at the reading part which prevents to continue the script and to update the file. Maybe this was printing in the Logcat but you haven't take a look.
So I'd suggest you to check if the file already exists and to separate the reading/writing parts.
When you first read the file to display it in TextView, just check if it's created to avoid a background exception:
File f = new File(getFilesDir().toString() + "/stars.txt");
Log.v("", "Does the file exist? " + f.exists());
if (f.exists()) {
readFile();
}
You can see here where the file should be stored (in getFilesDir()). The path is choosen by default when you use openFileInput(String), and it's:
data/data/com.package.name/files/
You have to keep in mind that you actually don't create /files folder in your code and for example, I had to create it myself to work with the above method. (This can be only my device but you'd be aware this can prevent the file to be created.)
Now, there is no big changes in your reading method and this is how it looks:
private void readFile() {
try {
FileInputStream file = openFileInput("stars.txt");
InputStreamReader inRead = new InputStreamReader(file);
BufferedReader buffReader = new BufferedReader(inRead);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star = buffReader.readLine()) != null) {
stringBuffer.append(star);
}
inRead.close();
file.close();
txt_stars.setText(stringBuffer.toString());
} catch (Exception e) {
Log.e("ReadFile", e.toString());
}
}
Obviously, this method is called only if the previous check returns true. You have to do the same when the Button is clicked: check if it exists -> if yes, get the content, do your stuff (add, sum, etc) and write into it -> if not, just create it by writing into it.
Something as follows will work:
public void writeFile(View v) {
File f = new File(getFilesDir().toString() + "/stars.txt");
Log.v("", "Does it exist? " + f.exists());
String result = "";
if ( f.exists() ) {
try {
FileInputStream file = openFileInput("stars.txt");
InputStreamReader inRead = new InputStreamReader(file);
BufferedReader buffReader = new BufferedReader(inRead);
StringBuffer stringBuffer = new StringBuffer();
String star;
while ((star=buffReader.readLine()) != null) {
stringBuffer.append(star);
}
result = stringBuffer.toString();
inRead.close();
file.close();
} catch (Exception e) {
Log.e("WriteFile", "--- Error on reading file: "+e.toString());
}
} else {
// get the user's star or whatever
result = editRating.getText().toString();
}
Log.v("WriteFile", "--- Read file returns: " + result);
stars = Integer.parseInt(result);
totalStars = stars + 50;
try {
FileOutputStream fileOut = openFileOutput("stars.txt", MODE_PRIVATE);
OutputStreamWriter outputWriter = new OutputStreamWriter(fileOut);
outputWriter.write(String.valueOf(totalStars));
outputWriter.close();
fileOut.close();
// display file saved message
Toast.makeText(getBaseContext(), "File saved", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(" WriteFile", e.toString());
}
}
At this point, when you returned to the previous activity, you should be able to see the changes.
However, in order to see the file in your storage, you unfortunately must to have a rooted device, else you'll see an empty folder. Then finally, you'd avoid to restart the Activity. You should finish the editing one, this will come back to the previous one, and you just have to call readFile() in onResume() instead of onCreate(). It will update the new content into the TextView.
Have you tried on updating textview before starting new Activity? Example:
txt_start.setText(""+totalStars);
Could you point me out to a code or url where I can find some examples how to use dropbox java api and upload binary files like, .doc files jpg and video files.
Current examples in the web only point to uploading a text file. But when I try to read files using java InputStream and convert them to byte array and pass into dropbox file upload functions files get corrupted. Same issue with downloading files as well. Thanks in Advance.
Regards,
Waruna.
EDIT--
Code Sample
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buf = new byte[1024];
for(int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
System.out.println("read "+ readNum + "bytes,");
}
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(bos.toByteArray());
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2, file.toString().length(), null, null);
System.out.println("Done. \nRevision of file: " + newEntry.rev + " " + newEntry.mimeType);
return newEntry.rev;
The 3rd argument of DropboxAPI.putFile() should be the number of bytes to read from the input stream - You are passing the length of the filename.
Instead of
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
file.toString().length(), null, null);
Use
Entry newEntry = mDBApi.putFile("/uploads/"+file.getName(), inputStream2,
bos.size(), null, null);
I don't think you need to convert to byte array, simply use FileInputStream is enough for a file, txt as well as binary. The following code works, I just tested with JPG.
DropboxAPI<?> client = new DropboxAPI<WebAuthSession>(session);
FileInputStream inputStream = null;
try {
File file = new File("some_pic.jpg");
inputStream = new FileInputStream(file);
DropboxAPI.Entry newEntry = client.putFile("/testing.jpg", inputStream,
file.length(), null, null);
System.out.println("The uploaded file's rev is: " + newEntry.rev);
} catch (DropboxUnlinkedException e) {
// User has unlinked, ask them to link again here.
System.out.println("User has unlinked.");
} catch (DropboxException e) {
System.out.println("Something went wrong while uploading.");
} catch (FileNotFoundException e) {
System.out.println("File not found.");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {}
}
}
I have a 7zip archive which contains some hundred files separated into different directories. The target is to download it from a FTP server and then extract it on the phone.
My problem is that the 7zip SDK doesn't contain a lot. I am looking for examples, tutorials and snippets regarding the decompression of 7z files.
(Decompression via Intent is only a secondary option)
Go here:
LZMA SDK just provides the encoder and decoder for encoding/decoding the raw data, but 7z archive is a complex format for storing multiple files.
i found this page that provides an alternative that works like a charm. You only have to add compile 'org.apache.commons:commons-compress:1.8'
to your build gradle script and use the feature you desire. For this issue i did the following :
AssetManager am = getAssets();
InputStream inputStream = null;
try {
inputStream = am.open("a7ZipedFile.7z");
File file1 = createFileFromInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
SevenZFile sevenZFile = null;
try{
File f = new File(this.getFilesDir(), "a7ZipedFile.7z");
OutputStream outputStream = new FileOutputStream(f);
byte buffer[] = new byte[1024];
int length = 0;
while((length=inputStream.read(buffer)) > 0) {
outputStream.write(buffer,0,length);
}
try {
sevenZFile = new SevenZFile(f);
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
while (entry != null) {
System.out.println(entry.getName());
FileOutputStream out = openFileOutput(entry.getName(), Context.MODE_PRIVATE);
byte[] content = new byte[(int) entry.getSize()];
sevenZFile.read(content, 0, content.length);
out.write(content);
out.close();
entry = sevenZFile.getNextEntry();
}
sevenZFile.close();
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}catch (IOException e) {
//Logging exception
e.printStackTrace();
}
The only draw back is approximately 200k for the imported library. Other than that it is really easy to use.