import java.io.*;
public class ReadFile {
public static void main(String[] args) throws IOException {
File in = new File("in.txt");
//File out = new File("out.txt");
FileOutputStream fos= new FileOutputStream("o.txt");
//PrintWriter fw= new PrintWriter(out);
if(!in.exists())
{
in.createNewFile();
//System.out.println("Hey");
}
FileReader is = new FileReader(in);
BufferedReader br= new BufferedReader(is);
while(true)
{
if(in.canRead())
{
try {
System.out.println(br.readLine());
fos.write((br.readLine()).getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
fos.close();
br.close();
System.out.println("Im breaking");
break;
}
}
else
{
fos.close();
System.out.println("closed");
break;
)
}
}
}
//end of file
I am trying to copy text from one file to another file in Java.I know we can copy byte by byte but i want to do it using strings! What's wrong?
Actual file :
Output file :
If you working with Java7 you can use Files.copy(source.toPath(), dest.toPath()); so you do not have to read the file. Or use FileUtils.copyFile(source, dest); from apache commons io.
System.out.println(br.readLine());
fos.write((br.readLine()).getBytes());
You
Read one line, print it to stdout
Read another line, write it to fos
Thus some lines may be missing from output file. Also, readLine() drops the line-termination characters. You need to add them back by yourself.
Related
The first method below (getMetadataTitle) simply retrieves the Title metadata from an mp3 file. It works fine. How would one write or update the Title metadata in the mp3 file, see the second method (putMetadataTitle) below?
private String getMetadataTitle(Context myContext, Uri myMp3) {
MediaMetadataRetriever retriever;
String title = null;
try {
retriever = new MediaMetadataRetriever();
retriever.setDataSource(myContext, myMp3);
title = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
} catch (Exception e) {
e.printStackTrace();
}
return title;
}
private void putMetadataTitle(String newTitle, Uri myMp3) {
// need help here!
}
Here is the completed putMetadataTitle() method from my question. I downloaded the MyID3_for_android jar file as suggested in question 9707572 and answers, How to get and set (change) ID3 tag (metadata) of audio files?.
private void putMetadataTitle(String newTitle, Uri myUri) {
File myMp3 = new File(myUri.getPath());
MusicMetadataSet mySet = null;
MusicMetadata myMetadata = new MusicMetadata("name");
try {
mySet = new MyID3().read(myMp3);
if (mySet == null) {
Log.i("NULL", "NULL");
} else {
myMetadata.setSongTitle(newTitle);
new MyID3().update(myMp3, mySet, myMetadata);
}
} catch (Exception e) {
e.printStackTrace();
}
}
My purpose is to upload the file on primary location synchronously and same time upload same file on multiple secondary locations asynchronously. So can you please help me to implement multi threading for secondary locations writing(e.g. same file to write multiple paths simultaneously while reading it)
Below is a code to read from input stream
List<FileUploadMultiLocator> fileUploadList = new ArrayList<>();
FileUploadMultiLocator fum1 = new FileUploadMultiLocator("fileserver0", new BufferedOutputStream(new FileOutputStream(new File(reposMap.get("D:\\Harisingh\\FileUpload\\Destination1.txt")))));
FileUploadMultiLocator fum2 = new FileUploadMultiLocator("fileserver0", new BufferedOutputStream(new FileOutputStream(new File(reposMap.get("D:\\Harisingh\\FileUpload\\Destination2.txt")))));
fileUploadList.add(fum1);
fileUploadList.add(fum2);
while((len=channel.read(byteBuffer))>=0)
{
itrCount++;
totalBytes+=len;
baOS.write(byteBuffer.array(),0,len);
if(itrCount>=maxIterateCnt)
{
//primary location writing
bFout.write(baOS.toByteArray(),0,totalBytes);
// this is for secondary location writing
for (FileUploadMultiLocator fileUploadMultiLocator : fileUploadList) {
fileUploadMultiLocator.baOS = baOS;
fileUploadMultiLocator.totalBytes = totalBytes;
new Thread(fileUploadMultiLocator).start();
}
totalBytes=0;
baOS.reset();
itrCount=0;
}
byteBuffer.clear();
}
This is my runnable class to write multiple BufferedOutputStream same time
public class FileUploadMultiLocator implements Runnable{
public FileUploadMultiLocator(String fileserver,BufferedOutputStream bFout) {
// TODO Auto-generated constructor stub
this.fileserver = fileserver;
this.bFout = bFout;
}
#Override
public void run() {
// TODO Auto-generated method stub
try
{
bFout.write(baOS.toByteArray(),0,totalBytes);
bFout.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
i am writing my own image import for my product catalog. I want to read the images from the local filesystem and store them in the configured assets folder. The import is very simple for now. Its one controller in the admin project and i trigger it by calling an url.
It is creating the files along with the folder structure and the files seem to have the same filesize, but somehow they get messed up along the way and they are not readable as images anymore (picture viewers wont open them). Any ideas why its being messed up ?
here the code:
#Controller("blImageImportController")
#RequestMapping("/imageimport")
public class ImageImportController extends AdminAbstractController {
#Value("${image.import.folder.location}")
private String importFolderLocation;
#Resource(name = "blStaticAssetService")
protected StaticAssetService staticAssetService;
#Resource(name = "blStaticAssetStorageService")
protected StaticAssetStorageService staticAssetStorageService;
#RequestMapping(method = {RequestMethod.GET})
public String chooseMediaForMapKey(HttpServletRequest request,
HttpServletResponse response,
Model model
) throws Exception {
File imageImportFolder = new File(importFolderLocation);
if (imageImportFolder.isDirectory()) {
Arrays.stream(imageImportFolder.listFiles()).forEach(directory ->
{
if (directory.isDirectory()) {
Arrays.stream(directory.listFiles()).forEach(this::processFile);
}
});
}
return "";
}
private void processFile(File file) {
FileInputStream fis = null;
try {
HashMap properties = new HashMap();
properties.put("entityType", "product");
properties.put("entityId", file.getParentFile().getName());
fis = new FileInputStream(file);
StaticAsset staticAsset = this.staticAssetService.createStaticAsset(fis, file.getName(), file.length(), properties);
this.staticAssetStorageService.createStaticAssetStorage(fis, staticAsset);
fis.close();
} catch (Exception e) {
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
There is a check in the StaticAssetService to try to detect this as an image (see https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetServiceImpl.java#L217-L220). If it detected this correctly, you should get back an ImageStaticAssetImpl in the result to that call.
The flipside of this is the controller that actually reads the file (the StaticAssetViewController that renders a StaticAssetView). One of the things that the StaticAssetView does is set a response header for mimeType which the browser uses to render. This is set by this piece in the StaticAssetStorageService: https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f837f26022a620f0c2c143eed7902ba3f1/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetStorageServiceImpl.java#L213. I suspect that is the root of your problem.
Also just a note, sending those properties is not necessary when you are uploading the file yourself. That is mainly used in the admin when you are uploading an image for a specific entity (like a product or a category).
I'm using asyncTask to download some files over the internet. This is the code I've written which works
downloadUrl task = new downloadUrl(url1,"jsonData1","/sdcard/appData/LocalJson/jsonData1",context);
task.execute();
downloadUrl task1 = new downloadUrl(url2,"jsonData2","/sdcard/appData/LocalJson/jsonData2",context);
task1.execute();
downloadUrl task2 = new downloadUrl(url3,"jsonData3","/sdcard/appData/LocalJson/jsonData3",context);
task2.execute();
downloadUrl task3 = new downloadUrl(url4,"jsonData4","/sdcard/appData/LocalJson/jsonData4",context);
task3.execute();
Now, the tasks run in parallel considering the UI-Thread but they run serialized between one another, which is time consuming. So instead I've tried to execute them on the executor But the thing is that this way I'm missing some files, meaning that when they run serialized I end up with 38 files downloaded while the run on the Executor I end up with 20. I'm pretty sure that is, because I messed up something in the multi-threading code So I'll post it that to:
#Override
protected String doInBackground(String... args) {
downloadAndStoreJson(url,targetFolder);
JSONObject jsonObj = loadJSONObject(pathForLoad);
try {
processJsonData(jsonObj);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "done";
}
#Override
protected void onPostExecute(String result) {
s(targetFolder+" Finished!");
++mutex;
progressBar.setProgress(25*mutex);
if(mutex==4){
mutex=0;
progressBar.setProgress(100);
progressBar.dismiss();
s(monuments.size());
Intent intent = new Intent (getApplicationContext(),NextClass.class);
intent.putExtra("monuments", monuments);
startActivity(intent);
}
}
private void downloadAndStoreJson(String url,String tag){
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(url);
String jsonString = json.toString();
byte[] jsonArray = jsonString.getBytes();
File fileToSaveJson = new File("/sdcard/appData/LocalJson/",tag);
BufferedOutputStream bos;
try {
bos = new BufferedOutputStream(new FileOutputStream(fileToSaveJson));
bos.write(jsonArray);
bos.flush();
bos.close();
} catch (FileNotFoundException e4) {
// TODO Auto-generated catch block
e4.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
jsonArray=null;
jParser=null;
System.gc();
}
}
private JSONObject loadJSONObject(String path){
JSONObject jsonObj = null;
File readFromJson = new File(path);
byte[] lala;
try {
lala= org.apache.commons.io.FileUtils.readFileToByteArray(readFromJson);
s("---------------"+lala.length);
String decoded = new String(lala, "UTF-8");
jsonObj = new JSONObject(decoded);
} catch (IOException e5) {
// TODO Auto-generated catch block
e5.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObj;
}
and processJsonData is a long method which parses the json files, creates objects and then stores them in an ArrayList, that's where a problem might exist.
You need to make sure your code is Reentrant, meaning it must be possible to run it by several threads at the same time. Or if some code is used to syncronize the execution between your threads you need to make sure it is synchronized.
Looking at your code I see that the mutex is a static variable, which you use to keep track of your threads. Make sure that the operation on the mutex is synchronized, just to keep it clean. But that will not cause you problem...
I dont see your error in this code-snippet, either I fail to see the problem or it might be located in some other methods? Can you please share "downloadAndStoreJson"?
I'm using Wicket (not sure if it matters) but I'm using Workbook to create an excel file for a user to download. But I'm not sure how exactly to do this. What I would like to happen is the user clicks the button, a log is created and a prompt is given to the user to open (and save to temp files) or to save to their computer. The file is then deleted from the server side, or maybe it is stored in the User's session and deleted at end of session.
Can someone point me in the right direction? If I can have the file not saved in the session at all, that'd be create and have it just have it sent to the client using FileOutputStream somehow..
here is my current code:
private void excelCreator()
{
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("SSA User ID " + currentSSAIDSelection2.getSsaUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream("ssaUserIDAccess.xls");
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
You would have to create a DownloadLink with the temporary file as input. The temporary File must be deleted after download (file.delete())).
Alternatively you can try this:
IResourceStream stream = new ByteArrayResourceStream(data, "application/vnd.ms-excel");
RequestCycle.get().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(stream, filename).setContentDisposition(ContentDisposition.ATTACHMENT));
In this case data is the byte[] content of your workbook which can be for example retrieved with output.toByteArray().
In case anyone runs into this problem here is my solution. There wasn't a lot of straight forward answers on this but this is my solution:
My excelCreator method handles the creation of the excel Sheet, and returns it as a file.
private File excelCreator()
{
Workbook workbook = new HSSFWorkbook();
File excelfile = new File("userIDAccess.xls");
logList = getServer().findAuditLogs(getUserId(), null);
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("User ID " + getUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream(excelfile);
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
return excelfile;
}
IModel excelFileModel = new AbstractReadOnlyModel()
{
public Object getObject()
{
return excelCreator();
}
};
I created an IModel to capture the file created inside my excelCreator() method and returned.
auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);
I pass the I.D. of the download link, and then pass the imodel.
finally,
I call,
auditDownloadlink.setDeleteAfterDownload(true);
auditDownloadlink.setCacheDuration(Duration.NONE);
This deletes the file after it is created. And the cache setting is a setting to make sure it is compatible with all browsers (That's how I interpreted it, but you may not need it).
The Imodel creates the File on the fly so it doesn't have to be stored anywhere, and then the file is deleted once it is downloaded.
Hope this helps someone!
You could create a Resource to do this, and make a ResourceLink.
public class ExcelProducerResource extends AbstractResource
{
public ExcelProducerResource()
{
}
#Override
protected ResourceResponse newResourceResponse( Attributes attributes )
{
final String fileName = getFileName();
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
resourceResponse.setCacheDuration( Duration.NONE );
resourceResponse.setFileName( fileName );
resourceResponse.setWriteCallback( new WriteCallback()
{
#Override
public void writeData( Attributes attributes ) throws IOException
{
OutputStream outputStream = attributes.getResponse().getOutputStream();
writeToStream( outputStream );
outputStream.close();
}
} );
return resourceResponse;
}
void writeToStream(OutputStream outputStream) throws IOException
{
//.. do stuff here :)
}
String getFileName()
{
//.. do stuff here :)
}
}