In an Android project I am reading an audio file into an InputStream and consequently write it to another location on the device. When reading, in.read(buffer) as shown in the snippet returns -1. After running the app, I locate the file using the phone's file manager app to play. But it doesn't play because the file is empty, i.e. size is 0 bytes. What is the right way to read and write audio files in using InputStreams and OutputStreams?
try {
DocumentFile newFile = pickedDir.createFile("audio/mp3", "New File");
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
InputStream in = new FileInputStream("/storage/emulated/0/beat.mp3");
// To check whether the source file exists
File testFile = File("/storage/emulated/0/beat.mp3");
Log.d("App", "exists: " + testFile.exists() + " len: " + testFile.length());//exists: true len: 0
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {
Log.d("Exception ", e.getMessage());
}
to be pedantic, use:
FileInputStream in = new FileInputStream("/storage/emulated/0/beat.mp3");
And just make sure the path is correct and the file exists. Other than that, from the info you gave, I cannot think of anything else
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
InputStream in = new FileInputStream("/storage/emulated/0/beat.mp3");
File newFile = File("/storage/emulated/0/beat.mp3");
Seem your code have problem here, newFile.getUri() is called before it init?
Related
How we can push multiple files from our local folder to smb share folder using java. I can do with my single file using smbFile and it is working. I am looking for pushing multiple file push to smb share.
Any reference links and sample code would be helpful.
Thanks.
EDIT, Reference of code :
SmbFile[] files = getSMBListOfFiles(sb, logger, domain, userName, password, sourcePath, sourcePattern);
if (files == null)
return false;
output(sb, logger, " Source file count: " + files.length);
String destFilename;
FileOutputStream fileOutputStream;
InputStream fileInputStream;
byte[] buf;
int len;
for (SmbFile smbFile: files) {
destFilename = destinationPath + smbFile.getName();
output(sb, logger, " copying " + smbFile.getName());
try {
fileOutputStream = new FileOutputStream(destFilename);
fileInputStream = smbFile.getInputStream();
buf = new byte[16 * 1024 * 1024];
while ((len = fileInputStream.read(buf)) > 0) {
fileOutputStream.write(buf, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
} catch (SmbException e) {
OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, SMP issue: " + e.getMessage(), e);
e.printStackTrace();
return false;
}
This works fine if i try to send one single file of anyformat. But if would like to send multiple file to smb share fromocal folder. For This i need thr help please. Thanks.
Try to declare a SmbFile object that is a root folder of your folder, that you want to upload to the shared folder. Then iterate through the root.listFiles() array.
Put the uploadable files in that folder.
I assume that, your SmbFile[] files array only contains one file if it's only uploading one file.
Or another possible solution is that, try to use SmbFileOutputStream and SmbFileInputStream instead of FileOutputStream and FileInputStream.
I'm guessing you are using jcifs-library (which is quite outdated), so firstly I would recommend you to switch library. I switched to SMBJ and here is how I'm uploading file:
private static void upload(File source, DiskShare diskShare, String destPath, boolean overwrite) throws IOException {
try (InputStream is = new java.io.FileInputStream(source)) {
if (destPath != null && is != null) {
// https://learn.microsoft.com/en-us/windows/win32/fileio/creating-and-opening-files
Set<AccessMask> accessMask = new HashSet<>(EnumSet.of(
AccessMask.FILE_READ_DATA,
AccessMask.FILE_WRITE_DATA, AccessMask.DELETE));
Set<SMB2ShareAccess> shareAccesses = new HashSet<>(
EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE));
Set<FileAttributes> createOptions = new HashSet<>(
EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL));
try (com.hierynomus.smbj.share.File file = diskShare
.openFile(destPath, accessMask, createOptions,
shareAccesses,
(overwrite
? SMB2CreateDisposition.FILE_OVERWRITE_IF
: SMB2CreateDisposition.FILE_CREATE),
EnumSet.noneOf(SMB2CreateOptions.class))) {
int bufferSize = 2048;
if (source.length() > 20971520l) {
bufferSize = 131072;
}
byte[] buffer = new byte[bufferSize];
long fileOffset = 0;
int length = 0;
while ((length = is.read(buffer)) > 0) {
fileOffset = diskShare.getFileInformation(destPath)
.getStandardInformation().getEndOfFile();
file.write(buffer, fileOffset, 0, length);
}
file.flush();
file.close();
} finally {
is.close();
}
}
}
}
Of course takes a little effort on connecting the SMB-server and authenticating before this, but that's another case...
I have android app that downloads compressed files and then decompress it ..
it works fine with English name files..
but if the file with Arabic name it make error malformated
E/UncaughtException: java.lang.IllegalArgumentException: MALFORMED[1]
this is my code..
appreciate your help
Thanks
private boolean unpackZip(String path, String zipname)
{
InputStream is;
ZipInputStream zis;
try
{
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null)
{
filename = ze.getName();
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(path + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(path + filename);
while ((count = zis.read(buffer)) != -1)
{
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
}
catch(IOException e)
{
e.printStackTrace();
return false;
}
return true;
}
Try
new ZipInputStream(new BufferedInputStream(is), Charset.forName("Windows-1256"));
as default is UTF-8 and that evidently did not work.
After feedback: evidently there is some Android API version problem.
You could inspect:
filename = ze.getName();
Sometimes one can "patch" the encoding. Very error prone, or even not feasible.
filename = new String(filename.getBytes("..."), "...");
where one might try different encodings:
Windows-1256
UTF-8
(Especially converting to UTF-8 might raise conversion errors, as UTF-8 requires the bytes to have a specific bit pattern for multibyte sequences.)
I'm trying to get save a text file from the internet into a folder in my res directory (res/files) so I can then read and interpret it. My android manifest has set the appropiate permissions but when I test it in the simulator it fails.
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
Here's the method to get the file:
public void getTextFile(){
String path ="http://hullmc.org.uk/cjvize/test.txt";
URL u = null;
try {
u = new URL(path);
BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));
int i = 0;
String replicated = "";
do{
String str = in.readLine();
replicated = replicated + "/n" + str;
i++;
}while(i<85);
in.close();
}
catch(Exception e){
welcome.setText("Failed");
}
}
Can anyone suggest why this is not working? Many thanks!
This is working fine for me :
Use of class variable for View and Activity allow to keep code centralaized and shared, passing view as parameter, updated in constructor :)
1) Code to store the file locally
View newReport;
Activity reportActivity;
private void downloadFile(String fileUrl, String fileName) {
try{
InputStream is = (InputStream) new URL(fileUrl).getContent();
FileOutputStream output = reportActivity.openFileOutput(fileName, newReport.getContext().MODE_PRIVATE);
byte data[] = new byte[1024];
int count;
while ((count = is.read(data)) != -1)
output.write(data, 0, count);
output.flush();
output.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
It saves the file on the internal storage.
Then to save a file from URL, just call:
downloadFile(myFileUrl, mySaveToFileName);
And to list your local files available:
String[] fileList = newReport.getContext().fileList();
for (String s : fileList){
System.out.println("File found : "+s);
}
Note: you do not require to save it locally to read it. If you prefer just to read it (to extract some info), let me know.
2) Code to "read and save to database", this should resolve:
// After InputStream declaration:
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
//TODO Update database row concatenating inputLine to existing text value.
}
in.close();
in=null;
is.close();
you can't save into the resource folder of your app. you can't even store files into the assets folder.
there aren't even such folders when you install the app - they are all zipped into the APK . the res folder is a special one too, because each file there also creates a constant in the "R.java" file, so that it would be easier to reach and use. you can't reach such a thing when it's dynamic...
what you can do is to choose the right folder for you (read here), and download the file into there, using something like this :
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(fullFilePath);
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1)
output.write(data, 0, count);
//todo close streams and handle exceptions
if you use Apache commons library, you could minimize the code to just one line:
IOUtils.copy(new BufferedInputStream(url.openStream()), new FileOutputStream(fullFilePath));
I want to retrieve file from ftp server, I have also used Apache poi client.retrieveFile() method, but I'm unable to open it which is showing:
excel cannot open file check file extension and file format. check file is not corrupted
Then I used file reader and writer. Below is my code snippet.
public void testFileWriter()
{
try{
FTPFile[] files = client.listFiles("/Ftp1");
for (FTPFile file : files) {
File serverFile = new File("D:/Pondi.xlsx");
if(!serverFile.isFile())
{
serverFile.createNewFile();
}
BufferedWriter writer = new BufferedWriter(new FileWriter(serverFile));
client.enterLocalPassiveMode();
InputStream inputStream = client.retrieveFileStream("/Ftp1/"+ file.getName());
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println("Created Reader");
while(reader.read()!=-1)
{
String temp = reader.readLine();
System.out.println(temp);
writer.write(temp);
}
writer.flush();
writer.close();
reader.close();
}
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
Please help me to resolve this crucial issue.
You have to use an API for working with it. You can't read these files like reading normal text files.
JExcel will be good for your need.
Examples are be available here
For copying files make use of this. Reading the file for copying by the method that you used won't work properly.
Hope will be helpful for you.
If you want to read and copy binary data, you must not use reader.readLine(), because there are no lines in a binary file. Therefore, this attempt will most likely fail.
Copy it like this instead:
int fileNo = 0;
for (FTPFile file : files) {
File serverFile = new File("D:/Pondi_" + fileNo + ".xlsx");
...
InputStream in = client.retrieveFileStream("/Ftp1/"+ file.getName());
OutputStream out = new FileOutputStream(serverFile);
// read and copy binary data
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
fileNo++;
}
Beside that, consider giving your files a different name that D:/Pondi.xlsx, because otherwise the file gets overridden again and again in the loop. I did this with fileNo.
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) {}
}
}